Import Necessary Files
!pip3 uninstall opencv-contrib-python opencv-python -y
!pip3 install opencv-contrib-python
!pip install imutils
import pandas as pd
import numpy as np
import re
import os
import cv2
import random
import matplotlib.pyplot as plt
%matplotlib inline
import seaborn as sns
from PIL import Image
import datetime
from tqdm import tqdm
import time
from matplotlib.patches import Rectangle
import csv
from skimage import measure
from skimage.transform import resize
import matplotlib.patches as patches
from tensorflow import keras
import sys
import math
import json
import glob
import io
import h5py
from imutils import paths
import imutils
# Import all the necessary libraries.
random.seed(1)
np.random.seed(1)
import warnings
warnings.filterwarnings(action='ignore', category=FutureWarning)
!pip install pydicom
import pydicom
from sklearn.model_selection import KFold
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.metrics import accuracy_score,confusion_matrix,precision_score,recall_score,f1_score,classification_report, confusion_matrix
from sklearn.metrics import roc_curve, roc_auc_score
from sklearn.preprocessing import LabelBinarizer
from sklearn.feature_extraction.image import extract_patches_2d
from keras import initializers
from keras.initializers import RandomNormal, HeNormal, GlorotNormal
from keras import Model, optimizers
from keras.models import Sequential, load_model, Model
from keras.layers import Conv2D, Flatten, Dense, MaxPooling2D, Dropout , BatchNormalization, GlobalMaxPooling2D
from keras.layers import activation, LeakyReLU, Input, AveragePooling2D, GlobalAveragePooling2D, Lambda
from keras.callbacks import EarlyStopping, ModelCheckpoint, ReduceLROnPlateau
from keras.optimizers import Adam, SGD, RMSprop, Adadelta, Adagrad, Adamax, Nadam
from keras.wrappers.scikit_learn import KerasClassifier
from keras.preprocessing.image import ImageDataGenerator
from keras.applications import VGG16
from keras.applications.vgg16 import VGG16
from keras.applications import MobileNetV2
from keras.applications.mobilenet_v2 import preprocess_input
from keras.applications import ResNet50, ResNet101, InceptionV3, MobileNet, EfficientNetB0, VGG19
from keras.utils import img_to_array, load_img, to_categorical
from sklearn.model_selection import RandomizedSearchCV
import tensorflow as tf
import pickle
import PIL
import time
from matplotlib.patches import Rectangle
from PIL import Image
import albumentations as A
from albumentations.pytorch.transforms import ToTensorV2
import torch
import torchvision
from torchvision.models.detection.faster_rcnn import FastRCNNPredictor
from torchvision.models.detection import FasterRCNN
from torchvision.models.detection.rpn import AnchorGenerator
from torch.utils.data import DataLoader, Dataset
from torch.utils.data.sampler import SequentialSampler
from matplotlib import pyplot as plt
Found existing installation: opencv-contrib-python 4.8.0.76 Uninstalling opencv-contrib-python-4.8.0.76: Successfully uninstalled opencv-contrib-python-4.8.0.76 WARNING: Skipping opencv-python as it is not installed. Collecting opencv-contrib-python Using cached opencv_contrib_python-4.8.0.76-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (67.8 MB) Requirement already satisfied: numpy>=1.21.2 in /opt/conda/lib/python3.10/site-packages (from opencv-contrib-python) (1.23.5) Installing collected packages: opencv-contrib-python Successfully installed opencv-contrib-python-4.8.0.76 Requirement already satisfied: imutils in /opt/conda/lib/python3.10/site-packages (0.5.4)
/opt/conda/lib/python3.10/site-packages/scipy/__init__.py:146: UserWarning: A NumPy version >=1.16.5 and <1.23.0 is required for this version of SciPy (detected version 1.23.5
warnings.warn(f"A NumPy version >={np_minversion} and <{np_maxversion}"
/opt/conda/lib/python3.10/site-packages/tensorflow_io/python/ops/__init__.py:98: UserWarning: unable to load libtensorflow_io_plugins.so: unable to open file: libtensorflow_io_plugins.so, from paths: ['/opt/conda/lib/python3.10/site-packages/tensorflow_io/python/ops/libtensorflow_io_plugins.so']
caused by: ['/opt/conda/lib/python3.10/site-packages/tensorflow_io/python/ops/libtensorflow_io_plugins.so: undefined symbol: _ZN3tsl6StatusC1EN10tensorflow5error4CodeESt17basic_string_viewIcSt11char_traitsIcEENS_14SourceLocationE']
warnings.warn(f"unable to load libtensorflow_io_plugins.so: {e}")
/opt/conda/lib/python3.10/site-packages/tensorflow_io/python/ops/__init__.py:104: UserWarning: file system plugins are not loaded: unable to open file: libtensorflow_io.so, from paths: ['/opt/conda/lib/python3.10/site-packages/tensorflow_io/python/ops/libtensorflow_io.so']
caused by: ['/opt/conda/lib/python3.10/site-packages/tensorflow_io/python/ops/libtensorflow_io.so: undefined symbol: _ZTVN10tensorflow13GcsFileSystemE']
warnings.warn(f"file system plugins are not loaded: {e}")
Requirement already satisfied: pydicom in /opt/conda/lib/python3.10/site-packages (2.4.1)
# Read the CSV files
detailed_df = pd.read_csv('/kaggle/input/pneumonia-dataset/stage_2_detailed_class_info.csv')
train_df = pd.read_csv('/kaggle/input/pneumonia-dataset/stage_2_train_labels.csv')
print(detailed_df.shape)
print(train_df.shape)
(30227, 2) (30227, 6)
Observations:
The detailed CSV file contains 30227 entries and 2 columns.
The Train Labels CSV file contains 30227 entries and 6 columns.
print(detailed_df.head())
patientId class 0 0004cfab-14fd-4e49-80ba-63a80b6bddd6 No Lung Opacity / Not Normal 1 00313ee0-9eaa-42f4-b0ab-c148ed3241cd No Lung Opacity / Not Normal 2 00322d4d-1c29-4943-afc9-b6754be640eb No Lung Opacity / Not Normal 3 003d8fa0-6bf1-40ed-b54c-ac657f8495c5 Normal 4 00436515-870c-4b36-a041-de91049b9ab4 Lung Opacity
print(train_df.head())
patientId x y width height Target 0 0004cfab-14fd-4e49-80ba-63a80b6bddd6 NaN NaN NaN NaN 0 1 00313ee0-9eaa-42f4-b0ab-c148ed3241cd NaN NaN NaN NaN 0 2 00322d4d-1c29-4943-afc9-b6754be640eb NaN NaN NaN NaN 0 3 003d8fa0-6bf1-40ed-b54c-ac657f8495c5 NaN NaN NaN NaN 0 4 00436515-870c-4b36-a041-de91049b9ab4 264.0 152.0 213.0 379.0 1
Observations:
Detailed dataframe contains Columns - patientId and class.
Train dataframe contains Columns - patientId, x, y , width, height and Target.
print('Unique Values of the Detailed Dataframe :', detailed_df['class'].unique())
print('Unique Values of the Train Label Dataframe:', train_df['Target'].unique())
Unique Values of the Detailed Dataframe : ['No Lung Opacity / Not Normal' 'Normal' 'Lung Opacity'] Unique Values of the Train Label Dataframe: [0 1]
print('Number of Unique Patient IDs in Detailed Dataframe : ',detailed_df['patientId'].nunique())
print('Number of Unique Patient IDs in Train Label Dataframe: ',train_df['patientId'].nunique())
Number of Unique Patient IDs in Detailed Dataframe : 26684 Number of Unique Patient IDs in Train Label Dataframe: 26684
Observations:
df = pd.concat([train_df,detailed_df["class"]],axis=1,sort=False)
df.head()
| patientId | x | y | width | height | Target | class | |
|---|---|---|---|---|---|---|---|
| 0 | 0004cfab-14fd-4e49-80ba-63a80b6bddd6 | NaN | NaN | NaN | NaN | 0 | No Lung Opacity / Not Normal |
| 1 | 00313ee0-9eaa-42f4-b0ab-c148ed3241cd | NaN | NaN | NaN | NaN | 0 | No Lung Opacity / Not Normal |
| 2 | 00322d4d-1c29-4943-afc9-b6754be640eb | NaN | NaN | NaN | NaN | 0 | No Lung Opacity / Not Normal |
| 3 | 003d8fa0-6bf1-40ed-b54c-ac657f8495c5 | NaN | NaN | NaN | NaN | 0 | Normal |
| 4 | 00436515-870c-4b36-a041-de91049b9ab4 | 264.0 | 152.0 | 213.0 | 379.0 | 1 | Lung Opacity |
Observations:
df.fillna(0,inplace=True)
fig, ax = plt.subplots(1, 2, figsize=(12,4))
pd.pivot_table(df,index=["Target"], values=['patientId'], aggfunc='count').plot.bar(title='Distribution of patients with Target', rot=0, color = 'turquoise', ax=ax[0])
pd.pivot_table(df,index=["class"], values=['patientId'], aggfunc='count').plot.bar(title='Distribution of patients with Classes', rot = 8, color = 'turquoise', ax=ax[1])
for i in ax[0].containers:
ax[0].bar_label(i,)
for i in ax[1].containers:
ax[1].bar_label(i,)
plt.show();
Observations:
pd.pivot_table(df, index = ['patientId'], aggfunc ='size')
patientId
0004cfab-14fd-4e49-80ba-63a80b6bddd6 1
000924cf-0f8d-42bd-9158-1af53881a557 1
000db696-cf54-4385-b10b-6b16fbb3f985 2
000fe35a-2649-43d4-b027-e67796d412e0 2
001031d9-f904-4a23-b3e5-2c088acd19c6 2
..
fffb2395-8edd-4954-8a89-ffe2fd329be3 2
fffba05a-1635-4545-9bbd-57ad4cfe8d27 1
fffc95b5-605b-4226-80ab-62caec682b22 1
fffcff11-d018-4414-971a-a7cefa327795 1
fffec09e-8a4a-48b1-b33e-ab4890ccd136 1
Length: 26684, dtype: int64
Observations:
As seen, there are multiple entries for the same patientID. Lets analyse further.
df[df['patientId'] == '000db696-cf54-4385-b10b-6b16fbb3f985']
| patientId | x | y | width | height | Target | class | |
|---|---|---|---|---|---|---|---|
| 28990 | 000db696-cf54-4385-b10b-6b16fbb3f985 | 316.0 | 318.0 | 170.0 | 478.0 | 1 | Lung Opacity |
| 28991 | 000db696-cf54-4385-b10b-6b16fbb3f985 | 660.0 | 375.0 | 146.0 | 402.0 | 1 | Lung Opacity |
Observations:
ax = df['patientId'].value_counts().value_counts().plot.bar(figsize=(6,4), title='Distribution of bounding boxes with patientId',
rot = 0, color = 'turquoise');
plt.yscale('log')
plt.xlabel('No. of Bounding Box')
plt.ylabel('No. of Patients')
for i in ax.containers:
ax.bar_label(i,)
Observations:
test_Image = pydicom.read_file('/kaggle/input/pneumonia-dataset/stage_2_train_images/stage_2_train_images/0004cfab-14fd-4e49-80ba-63a80b6bddd6.dcm')
test_Image
Dataset.file_meta ------------------------------- (0002, 0000) File Meta Information Group Length UL: 202 (0002, 0001) File Meta Information Version OB: b'\x00\x01' (0002, 0002) Media Storage SOP Class UID UI: Secondary Capture Image Storage (0002, 0003) Media Storage SOP Instance UID UI: 1.2.276.0.7230010.3.1.4.8323329.28530.1517874485.775526 (0002, 0010) Transfer Syntax UID UI: JPEG Baseline (Process 1) (0002, 0012) Implementation Class UID UI: 1.2.276.0.7230010.3.0.3.6.0 (0002, 0013) Implementation Version Name SH: 'OFFIS_DCMTK_360' ------------------------------------------------- (0008, 0005) Specific Character Set CS: 'ISO_IR 100' (0008, 0016) SOP Class UID UI: Secondary Capture Image Storage (0008, 0018) SOP Instance UID UI: 1.2.276.0.7230010.3.1.4.8323329.28530.1517874485.775526 (0008, 0020) Study Date DA: '19010101' (0008, 0030) Study Time TM: '000000.00' (0008, 0050) Accession Number SH: '' (0008, 0060) Modality CS: 'CR' (0008, 0064) Conversion Type CS: 'WSD' (0008, 0090) Referring Physician's Name PN: '' (0008, 103e) Series Description LO: 'view: PA' (0010, 0010) Patient's Name PN: '0004cfab-14fd-4e49-80ba-63a80b6bddd6' (0010, 0020) Patient ID LO: '0004cfab-14fd-4e49-80ba-63a80b6bddd6' (0010, 0030) Patient's Birth Date DA: '' (0010, 0040) Patient's Sex CS: 'F' (0010, 1010) Patient's Age AS: '51' (0018, 0015) Body Part Examined CS: 'CHEST' (0018, 5101) View Position CS: 'PA' (0020, 000d) Study Instance UID UI: 1.2.276.0.7230010.3.1.2.8323329.28530.1517874485.775525 (0020, 000e) Series Instance UID UI: 1.2.276.0.7230010.3.1.3.8323329.28530.1517874485.775524 (0020, 0010) Study ID SH: '' (0020, 0011) Series Number IS: '1' (0020, 0013) Instance Number IS: '1' (0020, 0020) Patient Orientation CS: '' (0028, 0002) Samples per Pixel US: 1 (0028, 0004) Photometric Interpretation CS: 'MONOCHROME2' (0028, 0010) Rows US: 1024 (0028, 0011) Columns US: 1024 (0028, 0030) Pixel Spacing DS: [0.14300000000000002, 0.14300000000000002] (0028, 0100) Bits Allocated US: 8 (0028, 0101) Bits Stored US: 8 (0028, 0102) High Bit US: 7 (0028, 0103) Pixel Representation US: 0 (0028, 2110) Lossy Image Compression CS: '01' (0028, 2114) Lossy Image Compression Method CS: 'ISO_10918_1' (7fe0, 0010) Pixel Data OB: Array of 142006 elements
Observations:
IMAGE_PATH = '/kaggle/input/pneumonia-dataset/stage_2_train_images/stage_2_train_images/'
IMAGE_PATH = '/kaggle/input/pneumonia-dataset/stage_2_train_images/stage_2_train_images/'
# Function to read dicom file from a Src Dataframe with PatientId as file name.
def read_metadata(src):
# Iterate over unique values of patientId and read the dcm file for that patientId
for n, index in tqdm(enumerate(src['patientId'].unique())):
data = pydicom.read_file(IMAGE_PATH+ '%s.dcm' % index)
# copy it to all the rows where the patient Id matches.
# Retreive "Age, Sex, and Position" information from metadata and copy it to Dataframe.
src.loc[src['patientId'] == data.PatientID ,'PatientAge'] = pd.to_numeric(data.PatientAge)
src.loc[src['patientId'] == data.PatientID ,'PatientSex'] = data.PatientSex
src.loc[src['patientId'] == data.PatientID ,'ViewPosition'] = data.ViewPosition
return src
final_df = df
final_df = read_metadata(final_df)
26684it [12:42, 35.01it/s]
final_df.head()
| patientId | x | y | width | height | Target | class | PatientAge | PatientSex | ViewPosition | |
|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0004cfab-14fd-4e49-80ba-63a80b6bddd6 | 0.0 | 0.0 | 0.0 | 0.0 | 0 | No Lung Opacity / Not Normal | 51.0 | F | PA |
| 1 | 00313ee0-9eaa-42f4-b0ab-c148ed3241cd | 0.0 | 0.0 | 0.0 | 0.0 | 0 | No Lung Opacity / Not Normal | 48.0 | F | PA |
| 2 | 00322d4d-1c29-4943-afc9-b6754be640eb | 0.0 | 0.0 | 0.0 | 0.0 | 0 | No Lung Opacity / Not Normal | 19.0 | M | AP |
| 3 | 003d8fa0-6bf1-40ed-b54c-ac657f8495c5 | 0.0 | 0.0 | 0.0 | 0.0 | 0 | Normal | 28.0 | M | PA |
| 4 | 00436515-870c-4b36-a041-de91049b9ab4 | 264.0 | 152.0 | 213.0 | 379.0 | 1 | Lung Opacity | 32.0 | F | AP |
plt.figure(figsize=(7,4))
cmap = plt.get_cmap('Accent')
my_colors = [cmap(i) for i in np.linspace(0, 1, 8)]
g = sns.countplot(x = 'class', hue = 'Target', data = final_df, palette = my_colors);
g.set_title('Distribution of Class by Target');
Observations:
plt.figure(figsize=(12,4))
plt.subplot(1,2,1)
g = final_df["class"].value_counts().plot(kind='pie',autopct='%1.0f%%', subplots=False, colors = my_colors);
g.set_title('Percentage Distribution of Class');
plt.subplot(1,2,2)
g = final_df["PatientSex"].value_counts().plot(kind='pie',autopct='%1.0f%%', subplots=False, colors = my_colors);
g.set_title('Percentage Distribution of Gender');
Observations:
fig = plt.figure(figsize=(10, 5))
plt.subplot(1,2,1)
g = sns.countplot(x = 'PatientSex', hue = 'Target', data = final_df, palette = my_colors);
g.set_title('Distribution of gender by Target');
plt.subplot(1, 2, 2)
g = sns.countplot(x = 'PatientSex', hue = 'class', data = final_df, palette = my_colors);
g.set_title('Distribution of gender by Class');
fig.tight_layout(pad=5.0)
plt.show();
Observations:
fig = plt.figure(figsize=(14, 5))
plt.subplot(1,3, 1)
g = final_df["ViewPosition"].value_counts().plot(kind='pie',autopct='%1.0f%%', subplots=False, colors = my_colors);
g.set_title('Percentage Distribution of View Position');
plt.subplot(1,3, 2)
g = sns.countplot(x = 'ViewPosition', hue = 'Target', data = final_df, palette = my_colors);
g.set_title('Distribution of View Position with Target')
plt.subplot(1, 3, 3)
g = sns.countplot(x = 'ViewPosition', hue = 'class', data = final_df, palette = my_colors);
g.set_title('Distribution of View Position for various classes')
fig.tight_layout(pad=5.0)
plt.show();
Observations:
final_df.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 30227 entries, 0 to 30226 Data columns (total 10 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 patientId 30227 non-null object 1 x 30227 non-null float64 2 y 30227 non-null float64 3 width 30227 non-null float64 4 height 30227 non-null float64 5 Target 30227 non-null int64 6 class 30227 non-null object 7 PatientAge 30227 non-null float64 8 PatientSex 30227 non-null object 9 ViewPosition 30227 non-null object dtypes: float64(5), int64(1), object(4) memory usage: 2.3+ MB
final_df['PatientSex'] = final_df['PatientSex'].astype('category')
final_df['ViewPosition'] = final_df['ViewPosition'].astype('category')
final_df['Target'] = final_df['Target'].astype('category')
final_df['class'] = final_df['class'].astype('category')
final_df['PatientAge'] = final_df['PatientAge'].astype('int')
final_df['x'] = final_df['x'].astype('int')
final_df['y'] = final_df['y'].astype('int')
final_df['width'] = final_df['width'].astype('int')
final_df['height'] = final_df['height'].astype('int')
plt.figure(figsize=(8,5))
g = sns.boxplot(x='class', y='PatientAge', data= final_df, palette = my_colors)
g.set_title('Distribution of Patient Age for various classes')
plt.show()
Observations:
final_df.describe(include = [np.number]).T
| count | mean | std | min | 25% | 50% | 75% | max | |
|---|---|---|---|---|---|---|---|---|
| x | 30227.0 | 124.561683 | 216.326397 | 0.0 | 0.0 | 0.0 | 193.0 | 835.0 |
| y | 30227.0 | 115.960962 | 190.012883 | 0.0 | 0.0 | 0.0 | 231.0 | 881.0 |
| width | 30227.0 | 69.060575 | 106.910496 | 0.0 | 0.0 | 0.0 | 169.0 | 528.0 |
| height | 30227.0 | 104.084825 | 176.932152 | 0.0 | 0.0 | 0.0 | 188.0 | 942.0 |
| PatientAge | 30227.0 | 46.797764 | 16.892940 | 1.0 | 34.0 | 49.0 | 59.0 | 155.0 |
Observations:
# IQR
Q1 = np.percentile(final_df['PatientAge'], 25, method='midpoint')
Q3 = np.percentile(final_df['PatientAge'], 75, method='midpoint')
IQR = Q3 - Q1
upper=Q3+1.5*IQR
print(upper)
print(final_df[final_df['PatientAge']>90]['PatientAge'])
96.5 3921 148 8635 92 11032 151 17213 153 20185 91 20186 91 25357 92 26488 150 27746 155 29674 91 Name: PatientAge, dtype: int64
Display all entries greater than 90 years old
final_df[final_df['PatientAge'] > 90]
| patientId | x | y | width | height | Target | class | PatientAge | PatientSex | ViewPosition | |
|---|---|---|---|---|---|---|---|---|---|---|
| 3921 | 3b8b8777-a1f6-4384-872a-28b95f59bf0d | 0 | 0 | 0 | 0 | 0 | Normal | 148 | M | PA |
| 8635 | 6108f7c0-96c4-48e6-994e-32e3cbeaf8d7 | 248 | 645 | 131 | 45 | 1 | Lung Opacity | 92 | M | AP |
| 11032 | 73aeea88-fc48-4030-8564-0a9d7fdecac4 | 0 | 0 | 0 | 0 | 0 | No Lung Opacity / Not Normal | 151 | F | PA |
| 17213 | a4e8e96d-93a6-4251-b617-91382e610fab | 0 | 0 | 0 | 0 | 0 | No Lung Opacity / Not Normal | 153 | M | PA |
| 20185 | b9a50c1f-4b93-4a91-963f-a8d06fe077ee | 150 | 212 | 273 | 484 | 1 | Lung Opacity | 91 | M | PA |
| 20186 | b9a50c1f-4b93-4a91-963f-a8d06fe077ee | 587 | 468 | 357 | 305 | 1 | Lung Opacity | 91 | M | PA |
| 25357 | e3314152-aa5f-4dff-93f8-93dc0bcbe57b | 0 | 0 | 0 | 0 | 0 | No Lung Opacity / Not Normal | 92 | M | PA |
| 26488 | ec3697bd-184e-44ba-9688-ff8d5fbf9bbc | 0 | 0 | 0 | 0 | 0 | Normal | 150 | M | PA |
| 27746 | f632328d-5819-4b29-b54f-adf4934bbee6 | 0 | 0 | 0 | 0 | 0 | Normal | 155 | F | PA |
| 29674 | 2118026e-ed2f-4d1e-baa2-0e9e1004f72c | 0 | 0 | 0 | 0 | 0 | Normal | 91 | F | PA |
Observations:
fig = plt.figure(figsize=(10, 4))
ax = fig.add_subplot(121)
g = sns.histplot(final_df['PatientAge'], color = 'orange')
g.set_title('Distribution of Patient Age');
ax = fig.add_subplot(122)
g = sns.histplot(final_df.loc[final_df['Target'] == 1, 'PatientAge'], color = 'turquoise')
g.set_title('Distribution of Patient Age having pneumonia');
from matplotlib.patches import Rectangle
def display_one_image(id, input_df):
# Create a plot
f, ax = plt.subplots(figsize=(5, 5))
# Read the file for the given patientId
data = pydicom.read_file(IMAGE_PATH + '%s.dcm' % id)
# Display the image
ax.imshow(data.pixel_array, cmap=plt.cm.bone)
ax.set_title('ID: {}\n Age: {} Sex: {}'.format(id, data.PatientAge, data.PatientSex))
# Copy all the rows where the patientId matches
filter = input_df[input_df['patientId'] == id]
# Collect data from all entries for a given patientId
for j, filtered_row in enumerate(list(filter.T.to_dict().values())):
x, y, width, height = filtered_row['x'], filtered_row['y'], filtered_row['width'], filtered_row['height']
rectangle = Rectangle(xy=(x,y),width=width, height=height, color="red",alpha = 0.2)
ax.add_patch(rectangle)
def display_image(input_df):
img_data = list(input_df.T.to_dict().values())
f, ax = plt.subplots(2,2, figsize=(12,15))
# Iterate through all the entries
for index, row in enumerate(img_data):
# Read the file for the given patientId
data = pydicom.read_file(IMAGE_PATH + '%s.dcm' % row['patientId'])
# Display the image
ax[index//2, index%2].imshow(data.pixel_array, cmap=plt.cm.bone)
ax[index//2, index%2].set_title('ID: {}\n Age: {} Sex: {}'.format(row['patientId'], data.PatientAge, data.PatientSex))
# Copy all the rows where the patientId matches
filter = input_df[input_df['patientId'] == row['patientId']]
# Collect data from all entries for a given patientId
for j, filtered_row in enumerate(list(filter.T.to_dict().values())):
x, y, width, height = filtered_row['x'], filtered_row['y'], filtered_row['width'], filtered_row['height']
rectangle = Rectangle(xy=(x,y),width=width, height=height, color="red",alpha = 0.2)
ax[index//2, index%2].add_patch(rectangle)
display_image(final_df[final_df['Target']==1].sample(n=4))
display_image(final_df[final_df['Target']==0].sample(n=4))
no_of_bbox = final_df['patientId'].value_counts()
four_bbox_df = final_df[final_df.patientId.isin(no_of_bbox.index[no_of_bbox.gt(3)])]
four_bbox_df.sample()
| patientId | x | y | width | height | Target | class | PatientAge | PatientSex | ViewPosition | |
|---|---|---|---|---|---|---|---|---|---|---|
| 11441 | 76f71a93-8105-4c79-a010-0cfa86f0061a | 673 | 303 | 106 | 145 | 1 | Lung Opacity | 43 | M | AP |
sample_id = '76f71a93-8105-4c79-a010-0cfa86f0061a'
display_one_image(sample_id, four_bbox_df[four_bbox_df['patientId'] == sample_id])
print('--'*40); print('Saving the feature engineered dataframe for future use'); print('--'*40)
final_df.to_pickle('/kaggle/working/train_data.pkl')
-------------------------------------------------------------------------------- Saving the feature engineered dataframe for future use --------------------------------------------------------------------------------
# Read `train_class_features.pkl` file, saved as EDA & Data Prep Module
final_df = pd.read_pickle('/kaggle/input/pneumonia-dataset/final_df.pkl')
For Image Classification problem, we do not intend to use other features.
Only Image will be our input to the model.
Since there is only one image per patient, drop the duplicates here.
final_df_unique = final_df.drop_duplicates('patientId', keep='last')
print('Shape of the Dataframe with Unique Patient IDs: ',final_df_unique.shape)
Shape of the Dataframe with Unique Patient IDs: (26684, 10)
## Checking the training data set with target distbution
ax = final_df_unique["Target"].value_counts().plot.bar(figsize=(6,4), title='Distribution of training data set with target',
rot = 0, color = 'turquoise');
plt.xlabel('Target')
plt.ylabel('No. of Patients')
for i in ax.containers:
ax.bar_label(i,)
## Just taking a few samples from the dataset.
sample_data = final_df_unique.groupby('Target', group_keys=False).apply(lambda x: x.sample(6000))
print('Shape of the Sample Dataframe to be input to model: ',sample_data.shape)
Shape of the Sample Dataframe to be input to model: (12000, 10)
ax = sample_data['Target'].value_counts().plot.bar(figsize=(5,4), title='Distribution of Sample dataset with target',
rot = 0, color = 'turquoise');
plt.xlabel('Target')
plt.ylabel('No. of Patients')
for i in ax.containers:
ax.bar_label(i,)
train, test = train_test_split(sample_data, test_size=0.3 , random_state=42,stratify=sample_data['Target'])
test, val= train_test_split(test, test_size = 0.5, random_state=42,stratify=test['Target'])
print('Shape of the Training Data : ',train.shape)
print('Shape of the Validation Data : ',val.shape)
print('Shape of the Testing Data : ',test.shape)
Shape of the Training Data : (8400, 10) Shape of the Validation Data : (1800, 10) Shape of the Testing Data : (1800, 10)
train.reset_index(inplace=True)
val.reset_index(inplace=True)
test.reset_index(inplace=True)
plt.figure(figsize=(15,4))
plt.subplot(1,3,1)
g = train['Target'].value_counts().plot(kind='pie',autopct='%1.0f%%', subplots=False, colors = my_colors);
g.set_title('Distribution of Target for Train Dataset');
plt.subplot(1,3,2)
g = val['Target'].value_counts().plot(kind='pie',autopct='%1.0f%%', subplots=False, colors = my_colors);
g.set_title('Distribution of Target for Validation Dataset');
plt.subplot(1,3,3)
g = test['Target'].value_counts().plot(kind='pie',autopct='%1.0f%%', subplots=False, colors = my_colors);
g.set_title('Distribution of Target for Test Dataset');
Observations:
def read_and_resize_images(final_df):
resized_images = []
boxes = []
for i in range(len(final_df)):
patient_id = final_df['patientId'][i]
target = final_df['Target'][i]
dicom_data = pydicom.read_file(os.path.join(IMAGE_PATH + '%s.dcm' % patient_id))
img = dicom_data.pixel_array
#Resize image to 32X32
img = cv2.resize(img, (32, 32))
# add trailing channel dimension
img = np.expand_dims(img, -1)
resized_images.append(img)
boxes.append(np.array(target, dtype=np.float32))
return np.array(resized_images), np.array(boxes)
# Read and resize training, validation and test images
X_train, y_train = read_and_resize_images(train)
X_val, y_val = read_and_resize_images(val)
X_test, y_test = read_and_resize_images(test)
X_train = np.array(X_train) / 255
X_val = np.array(X_val) / 255
X_test = np.array(X_test) / 255
# Checking the shape of train, test and validation sets
print('Shape of Training Data X: ', X_train.shape,'Y: ',y_train.shape )
print('Shape of Testing Data X: ', X_test.shape,'Y: ' , y_test.shape)
print('Shape of Validation Data X: ', X_val.shape,'Y: ',y_val.shape)
Shape of Training Data X: (8400, 32, 32, 1) Y: (8400,) Shape of Testing Data X: (1800, 32, 32, 1) Y: (1800,) Shape of Validation Data X: (1800, 32, 32, 1) Y: (1800,)
def save_pickle(dest, filename):
file = open(filename, 'wb')
# Pickle dictionary using protocol 0.
pickle.dump(dest, file)
file.close()
save_pickle(X_train, '/kaggle/working/X_train_data.pkl')
save_pickle(X_val, '/kaggle/working/X_val_data.pkl')
save_pickle(X_test, '/kaggle/working/X_test_data.pkl')
save_pickle(y_train, '/kaggle/working/y_train_data.pkl')
save_pickle(y_val, '/kaggle/working/y_val_data.pkl')
save_pickle(y_test, '/kaggle/working/y_test_data.pkl')
def open_pickle(filename):
file = open(filename, 'rb')
data = pickle.load(file)
file.close()
return data
X_train = open_pickle('/kaggle/working/X_train_data.pkl')
X_val = open_pickle('/kaggle/working/X_val_data.pkl')
X_test = open_pickle('/kaggle/working/X_test_data.pkl')
y_train = open_pickle('/kaggle/working/y_train_data.pkl')
y_val = open_pickle('/kaggle/working/y_val_data.pkl')
y_test = open_pickle('/kaggle/working/y_test_data.pkl')
Existing dataset can be modified and more samples can be created for training purpose which will help to avoid overfitting problem. The idea is to alter the training data with small transformations to reproduce the variations. Approaches that alter the training data in ways that change the array representation while keeping the label the same are known as data augmentation techniques. Commonly used techniques are grayscales, horizontal flips, vertical flips, random crops, color jitters, translations, rotations,etc.
Below parameters have been chosen for the data augmentation:
Once our model is ready, we fit the training dataset.
batch_size = 8
# Establish our metrics
METRICS = ['acc',
tf.keras.metrics.Precision(name='precision'),
tf.keras.metrics.Recall(name='recall')]
learning_rate_reduction = ReduceLROnPlateau(monitor='val_accuracy', patience = 2, verbose=1,factor=0.3, min_lr=0.000001)
early_stopping = EarlyStopping(monitor='val_loss',patience=5, restore_best_weights=True)
# Callbacks to reduce learning rate timely after monitoring a quantit
filepath="/kaggle/working/weights.hdf5"
checkpoint = ModelCheckpoint(filepath, monitor='val_acc', verbose=1, save_best_only=True, mode='max')
train_datagen = ImageDataGenerator(
featurewise_center=False, # set input mean to 0 over the dataset
samplewise_center=False, # set each sample mean to 0
featurewise_std_normalization=False, # divide inputs by std of the dataset
samplewise_std_normalization=False, # divide each input by its std
zca_whitening=False, # apply ZCA whitening
rotation_range = 30, # randomly rotate images in the range (degrees, 0 to 180)
zoom_range = 0.2, # Randomly zoom image
width_shift_range=0.1, # randomly shift images horizontally (fraction of total width)
height_shift_range=0.1, # randomly shift images vertically (fraction of total height)
horizontal_flip = True, # randomly flip images
vertical_flip=False) # randomly flip images
train_datagen.fit(X_train)
test_datagen = ImageDataGenerator()
train_generator = train_datagen.flow(X_train, y_train, batch_size=batch_size)
valid_generator = train_datagen.flow(X_val, y_val, batch_size=batch_size)
test_generator = test_datagen.flow(X_test, y_test, batch_size=1)
def fit_model(model):
history = model.fit(train_generator, epochs = NUM_OF_EPOCHS,
validation_data = valid_generator,
callbacks=[checkpoint,early_stopping,learning_rate_reduction],
batch_size=batch_size ,use_multiprocessing=True)
return history
Model 1 - Basic CNN Model
Model 2 - CNN Model with Batch Normalization
Model 3 - CNN Model with Leaky ReLU
Model 4 - CNN Model with Adam Optimizer
Since the problem statement is for binary classification, the below three metrics are being used for performance measurement. Accuracy, Precision, Recall
# Basic CNN Model
def create_model_1():
model = Sequential()
model.add(Conv2D(filters=32, kernel_size=3, activation='relu', input_shape = (32,32,1)))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Conv2D(filters=64, kernel_size=3, activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Conv2D(filters=32, kernel_size=3, activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Flatten())
model.add(Dense(activation='relu', units=128))
model.add(Dense(activation='sigmoid', units=1))
model.compile(optimizer = "rmsprop" , loss = 'binary_crossentropy' , metrics = METRICS)
model.summary()
return model
# Basic CNN Model with Batch Normalization
def create_model_2():
model = Sequential()
model.add(Conv2D(filters=32, kernel_size=3, activation='relu', input_shape = (32,32,1)))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Conv2D(filters=64, kernel_size=3, activation='relu'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Conv2D(filters=32, kernel_size=3, activation='relu'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Flatten())
model.add(Dense(activation='relu', units=128))
model.add(Dense(activation='sigmoid', units=1))
model.compile(optimizer = "rmsprop" , loss = 'binary_crossentropy' , metrics = METRICS)
model.summary()
return model
# Basic CNN Model with Leaky ReLU
def create_model_3():
model = Sequential()
model.add(Conv2D(32, (3, 3), activation=LeakyReLU(alpha=0.1), input_shape=(32, 32, 1)))
model.add(MaxPooling2D((2, 2)))
model.add(Conv2D(64, (3, 3), activation=LeakyReLU(alpha=0.1)))
model.add(MaxPooling2D((2, 2)))
model.add(Conv2D(128, (3, 3), activation=LeakyReLU(alpha=0.1)))
model.add(MaxPooling2D((2, 2)))
model.add(Flatten())
model.add(Dense(512, activation=LeakyReLU(alpha=0.1)))
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=METRICS)
model.summary()
return model
# Basic CNN Model with Adam as Optimizer
def create_model_4():
model = Sequential()
model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 1)))
model.add(MaxPooling2D((2, 2)))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D((2, 2)))
model.add(Conv2D(128, (3, 3), activation='relu'))
model.add(MaxPooling2D((2, 2)))
model.add(Flatten())
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))
model.compile(optimizer='adam', loss='binary_crossentropy', metrics = METRICS)
model.summary()
return model
Create a function that displays the performance metrics of the model. Metrics: Accuracy, Loss, ROC Curve, Classification Matrix Charts:
model_comparision_list = []
def get_model_prediction(model):
# Predict the values from the validation dataset
predictions = model.predict(X_test)
# Convert predictions classes to one hot vectors
return predictions.round().astype(int).tolist()
NUM_OF_EPOCHS = 12
FONT_SIZE = 10
def evaluate_model_perf(history, model, model_descr):
epochs = [i for i in range(len(history.history['acc']))] # Use the number of epochs actually trained
fig = plt.figure(figsize=(16,5 ))
plt.subplot(1,3,1)
plt.plot(epochs , history.history['acc'] , marker = 'o' ,color = 'orange', label = 'Training Accuracy')
plt.plot(epochs , history.history['val_acc'] , marker = 'o' ,color = 'turquoise', label = 'Validation Accuracy')
plt.title('Training & Validation Accuracy')
plt.legend(fontsize=FONT_SIZE)
plt.xticks(fontsize=FONT_SIZE)
plt.yticks(fontsize=FONT_SIZE)
plt.xlabel("Epochs", size=FONT_SIZE)
plt.ylabel("Accuracy", size=FONT_SIZE)
plt.subplot(1,3,2)
plt.plot(epochs , history.history['loss'] , marker = 'o' ,color = 'orange', label = 'Training Loss')
plt.plot(epochs , history.history['val_loss'] , marker = 'o' ,color = 'turquoise' , label = 'Validation Loss')
plt.title('Testing Accuracy & Loss')
plt.xticks(fontsize=FONT_SIZE)
plt.yticks(fontsize=FONT_SIZE)
plt.legend(fontsize=FONT_SIZE)
plt.xlabel("Epochs", size=FONT_SIZE)
plt.ylabel("Training & Validation Loss", size=FONT_SIZE)
# Calculate y_pred based on the validation set
y_pred = get_model_prediction(model)
## CONFUSION MATRIX
plt.subplot(1,3,3)
# Set up the labels for the confusion matrix
cm = confusion_matrix(y_test, y_pred)
labels = ['NORMAL', 'PNEUMONIA']
ax = sns.heatmap(cm, annot=True, fmt='d', cmap="GnBu", annot_kws={"fontsize": FONT_SIZE},
xticklabels = labels, yticklabels = labels)
ax.set(ylabel="True Label", xlabel="Predicted Label")
plt.title('Confusion Matrix')
plt.show()
plt.tight_layout()
print('\n\n\n')
print('--' * 40)
print("Classification Matrix")
print('--' * 40)
print(classification_report(y_test, y_pred,
target_names=['Normal (Class 0)', 'Pneumonia (Class 1)']))
print('--' * 40)
# performance_matrix list of this model
performance_matrix = []
performance_matrix.append(model_descr)
performance_matrix.append(accuracy_score(y_test, y_pred) * 100)
performance_matrix.append(precision_score(y_test, y_pred, average='macro') * 100)
performance_matrix.append(recall_score(y_test, y_pred, average='macro') * 100)
performance_matrix.append(f1_score(y_test, y_pred, average='macro') * 100)
# Store the performance per model
model_comparision_list.append(performance_matrix)
def display_ROC_comparision():
fig = plt.figure(figsize=(14,8))
y_pred_model_1 = get_model_prediction(model_1)
y_pred_model_2 = get_model_prediction(model_2)
y_pred_model_3 = get_model_prediction(model_3)
y_pred_model_4 = get_model_prediction(model_4)
## ROC CURVE
plt.subplot(2,2,3)
plt.title('ROC Curve for all models')
plt.plot([0, 1], [0, 1], 'k--', label = "Random (AUC = 50%)")
fpr, tpr, thresholds = roc_curve(y_test, y_pred_model_1)
auc_model = roc_auc_score(y_test, y_pred_model_1)
plt.plot(fpr, tpr, label='Model 1 (AUC = {:.2f}%)'.format(auc_model*100))
fpr, tpr, thresholds = roc_curve(y_test, y_pred_model_2)
auc_model = roc_auc_score(y_test, y_pred_model_2)
plt.plot(fpr, tpr, label='Model 2 (AUC = {:.2f}%)'.format(auc_model*100))
fpr, tpr, thresholds = roc_curve(y_test, y_pred_model_3)
auc_model = roc_auc_score(y_test, y_pred_model_3)
plt.plot(fpr, tpr, label='Model 3 (AUC = {:.2f}%)'.format(auc_model*100))
fpr, tpr, thresholds = roc_curve(y_test, y_pred_model_4)
auc_model = roc_auc_score(y_test, y_pred_model_4)
plt.plot(fpr, tpr, label='Model 4 (AUC = {:.2f}%)'.format(auc_model*100))
plt.xticks(fontsize=FONT_SIZE)
plt.yticks(fontsize=FONT_SIZE)
plt.xlabel('False Positive Rate', size=FONT_SIZE)
plt.ylabel('True Positive Rate', size=FONT_SIZE)
plt.legend(loc='best', fontsize=FONT_SIZE)
def display_model_matrix():
final_perf_df = pd.DataFrame(model_comparision_list, columns=['Model','Accuracy','Precision','Recall','F1 Score'])
final_perf_df.sort_values(by=['Accuracy'], inplace=True, ascending=False)
print('\n')
print('-'*80)
print("Model Performance Comparision Matrix")
print('-'*80)
print(final_perf_df)
print('-'*80)
model_1 = create_model_1()
history_1 = fit_model(model_1)
evaluate_model_perf(history_1, model_1, 'Basic_CNN_Model')
save_pickle(model_1, '/kaggle/working/model_1.pkl')
Model: "sequential_3"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_9 (Conv2D) (None, 30, 30, 32) 320
max_pooling2d_9 (MaxPooling (None, 15, 15, 32) 0
2D)
conv2d_10 (Conv2D) (None, 13, 13, 64) 18496
max_pooling2d_10 (MaxPoolin (None, 6, 6, 64) 0
g2D)
conv2d_11 (Conv2D) (None, 4, 4, 32) 18464
max_pooling2d_11 (MaxPoolin (None, 2, 2, 32) 0
g2D)
flatten_3 (Flatten) (None, 128) 0
dense_6 (Dense) (None, 128) 16512
dense_7 (Dense) (None, 1) 129
=================================================================
Total params: 53,921
Trainable params: 53,921
Non-trainable params: 0
_________________________________________________________________
Epoch 1/12
1045/1050 [============================>.] - ETA: 0s - loss: 0.6092 - acc: 0.6621 - precision: 0.6686 - recall: 0.6854
Epoch 1: val_acc did not improve from 0.72167
1050/1050 [==============================] - 17s 15ms/step - loss: 0.6088 - acc: 0.6619 - precision: 0.6681 - recall: 0.6847 - val_loss: 0.5716 - val_acc: 0.7028 - val_precision: 0.7044 - val_recall: 0.6989 - lr: 0.0010
Epoch 2/12
1050/1050 [==============================] - ETA: 0s - loss: 0.5720 - acc: 0.7020 - precision: 0.7003 - recall: 0.7064
Epoch 2: val_acc improved from 0.72167 to 0.72833, saving model to /kaggle/working/weights.hdf5
1050/1050 [==============================] - 16s 16ms/step - loss: 0.5720 - acc: 0.7020 - precision: 0.7003 - recall: 0.7064 - val_loss: 0.5501 - val_acc: 0.7283 - val_precision: 0.7134 - val_recall: 0.7633 - lr: 0.0010
Epoch 3/12
1050/1050 [==============================] - ETA: 0s - loss: 0.5656 - acc: 0.7095 - precision: 0.7074 - recall: 0.7148
Epoch 3: val_acc did not improve from 0.72833
1050/1050 [==============================] - 15s 15ms/step - loss: 0.5656 - acc: 0.7095 - precision: 0.7074 - recall: 0.7148 - val_loss: 0.5454 - val_acc: 0.7183 - val_precision: 0.7102 - val_recall: 0.7378 - lr: 0.0010
Epoch 4/12
1041/1050 [============================>.] - ETA: 0s - loss: 0.5578 - acc: 0.7242 - precision: 0.7234 - recall: 0.7250
Epoch 4: val_acc did not improve from 0.72833
1050/1050 [==============================] - 16s 15ms/step - loss: 0.5583 - acc: 0.7240 - precision: 0.7237 - recall: 0.7248 - val_loss: 0.5521 - val_acc: 0.7178 - val_precision: 0.6870 - val_recall: 0.8000 - lr: 0.0010
Epoch 5/12
1042/1050 [============================>.] - ETA: 0s - loss: 0.5567 - acc: 0.7174 - precision: 0.7164 - recall: 0.7188
Epoch 5: val_acc did not improve from 0.72833
1050/1050 [==============================] - 15s 15ms/step - loss: 0.5561 - acc: 0.7179 - precision: 0.7173 - recall: 0.7190 - val_loss: 0.5567 - val_acc: 0.7178 - val_precision: 0.6747 - val_recall: 0.8411 - lr: 0.0010
Epoch 6/12
1050/1050 [==============================] - ETA: 0s - loss: 0.5504 - acc: 0.7263 - precision: 0.7260 - recall: 0.7269
Epoch 6: val_acc improved from 0.72833 to 0.73111, saving model to /kaggle/working/weights.hdf5
1050/1050 [==============================] - 17s 16ms/step - loss: 0.5504 - acc: 0.7263 - precision: 0.7260 - recall: 0.7269 - val_loss: 0.5458 - val_acc: 0.7311 - val_precision: 0.7470 - val_recall: 0.6989 - lr: 0.0010
Epoch 7/12
1046/1050 [============================>.] - ETA: 0s - loss: 0.5509 - acc: 0.7272 - precision: 0.7290 - recall: 0.7243
Epoch 7: val_acc did not improve from 0.73111
1050/1050 [==============================] - 15s 15ms/step - loss: 0.5505 - acc: 0.7275 - precision: 0.7288 - recall: 0.7248 - val_loss: 0.5700 - val_acc: 0.7089 - val_precision: 0.8003 - val_recall: 0.5567 - lr: 0.0010
Epoch 8/12
1043/1050 [============================>.] - ETA: 0s - loss: 0.5493 - acc: 0.7253 - precision: 0.7254 - recall: 0.7247
Epoch 8: val_acc did not improve from 0.73111
1050/1050 [==============================] - 15s 15ms/step - loss: 0.5491 - acc: 0.7252 - precision: 0.7256 - recall: 0.7245 - val_loss: 0.5485 - val_acc: 0.7228 - val_precision: 0.7750 - val_recall: 0.6278 - lr: 0.0010
57/57 [==============================] - 0s 2ms/step
--------------------------------------------------------------------------------
Classification Matrix
--------------------------------------------------------------------------------
precision recall f1-score support
Normal (Class 0) 0.73 0.76 0.75 900
Pneumonia (Class 1) 0.75 0.72 0.73 900
accuracy 0.74 1800
macro avg 0.74 0.74 0.74 1800
weighted avg 0.74 0.74 0.74 1800
--------------------------------------------------------------------------------
<Figure size 640x480 with 0 Axes>
model_2 = create_model_2()
history_2 = fit_model(model_2)
evaluate_model_perf(history_2, model_2, 'CNN Model_Batch_Norm')
save_pickle(model_2, '/kaggle/working/model_2.pkl')
Model: "sequential_4"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_12 (Conv2D) (None, 30, 30, 32) 320
batch_normalization (BatchN (None, 30, 30, 32) 128
ormalization)
max_pooling2d_12 (MaxPoolin (None, 15, 15, 32) 0
g2D)
conv2d_13 (Conv2D) (None, 13, 13, 64) 18496
batch_normalization_1 (Batc (None, 13, 13, 64) 256
hNormalization)
max_pooling2d_13 (MaxPoolin (None, 6, 6, 64) 0
g2D)
conv2d_14 (Conv2D) (None, 4, 4, 32) 18464
batch_normalization_2 (Batc (None, 4, 4, 32) 128
hNormalization)
max_pooling2d_14 (MaxPoolin (None, 2, 2, 32) 0
g2D)
flatten_4 (Flatten) (None, 128) 0
dense_8 (Dense) (None, 128) 16512
dense_9 (Dense) (None, 1) 129
=================================================================
Total params: 54,433
Trainable params: 54,177
Non-trainable params: 256
_________________________________________________________________
Epoch 1/12
1048/1050 [============================>.] - ETA: 0s - loss: 0.6009 - acc: 0.6916 - precision: 0.7054 - recall: 0.6778
Epoch 1: val_acc did not improve from 0.73111
1050/1050 [==============================] - 20s 17ms/step - loss: 0.6007 - acc: 0.6918 - precision: 0.7052 - recall: 0.6778 - val_loss: 0.5711 - val_acc: 0.7089 - val_precision: 0.7582 - val_recall: 0.6133 - lr: 0.0010
Epoch 2/12
1047/1050 [============================>.] - ETA: 0s - loss: 0.5721 - acc: 0.7178 - precision: 0.7221 - recall: 0.7083
Epoch 2: val_acc did not improve from 0.73111
1050/1050 [==============================] - 17s 16ms/step - loss: 0.5721 - acc: 0.7179 - precision: 0.7221 - recall: 0.7083 - val_loss: 0.5589 - val_acc: 0.7128 - val_precision: 0.6944 - val_recall: 0.7600 - lr: 0.0010
Epoch 3/12
1042/1050 [============================>.] - ETA: 0s - loss: 0.5623 - acc: 0.7216 - precision: 0.7255 - recall: 0.7131
Epoch 3: val_acc did not improve from 0.73111
1050/1050 [==============================] - 17s 16ms/step - loss: 0.5624 - acc: 0.7218 - precision: 0.7255 - recall: 0.7136 - val_loss: 0.5634 - val_acc: 0.7172 - val_precision: 0.7005 - val_recall: 0.7589 - lr: 0.0010
Epoch 4/12
1047/1050 [============================>.] - ETA: 0s - loss: 0.5557 - acc: 0.7297 - precision: 0.7287 - recall: 0.7318
Epoch 4: val_acc did not improve from 0.73111
1050/1050 [==============================] - 18s 17ms/step - loss: 0.5560 - acc: 0.7294 - precision: 0.7286 - recall: 0.7312 - val_loss: 0.5770 - val_acc: 0.7117 - val_precision: 0.8029 - val_recall: 0.5611 - lr: 0.0010
Epoch 5/12
1049/1050 [============================>.] - ETA: 0s - loss: 0.5484 - acc: 0.7352 - precision: 0.7348 - recall: 0.7358
Epoch 5: val_acc did not improve from 0.73111
1050/1050 [==============================] - 17s 16ms/step - loss: 0.5484 - acc: 0.7352 - precision: 0.7350 - recall: 0.7357 - val_loss: 0.5583 - val_acc: 0.7089 - val_precision: 0.7094 - val_recall: 0.7078 - lr: 0.0010
Epoch 6/12
1043/1050 [============================>.] - ETA: 0s - loss: 0.5418 - acc: 0.7407 - precision: 0.7369 - recall: 0.7486
Epoch 6: val_acc did not improve from 0.73111
1050/1050 [==============================] - 18s 17ms/step - loss: 0.5430 - acc: 0.7396 - precision: 0.7355 - recall: 0.7483 - val_loss: 1.5557 - val_acc: 0.5017 - val_precision: 0.8000 - val_recall: 0.0044 - lr: 0.0010
Epoch 7/12
1041/1050 [============================>.] - ETA: 0s - loss: 0.5486 - acc: 0.7423 - precision: 0.7408 - recall: 0.7451
Epoch 7: val_acc did not improve from 0.73111
1050/1050 [==============================] - 17s 16ms/step - loss: 0.5476 - acc: 0.7425 - precision: 0.7413 - recall: 0.7450 - val_loss: 0.5467 - val_acc: 0.7272 - val_precision: 0.7055 - val_recall: 0.7800 - lr: 0.0010
Epoch 8/12
1048/1050 [============================>.] - ETA: 0s - loss: 0.5413 - acc: 0.7351 - precision: 0.7321 - recall: 0.7417
Epoch 8: val_acc did not improve from 0.73111
1050/1050 [==============================] - 17s 16ms/step - loss: 0.5414 - acc: 0.7350 - precision: 0.7319 - recall: 0.7417 - val_loss: 0.5710 - val_acc: 0.7122 - val_precision: 0.7736 - val_recall: 0.6000 - lr: 0.0010
Epoch 9/12
1049/1050 [============================>.] - ETA: 0s - loss: 0.5405 - acc: 0.7382 - precision: 0.7406 - recall: 0.7333
Epoch 9: val_acc improved from 0.73111 to 0.73722, saving model to /kaggle/working/weights.hdf5
1050/1050 [==============================] - 17s 17ms/step - loss: 0.5404 - acc: 0.7382 - precision: 0.7407 - recall: 0.7331 - val_loss: 0.5415 - val_acc: 0.7372 - val_precision: 0.7755 - val_recall: 0.6678 - lr: 0.0010
Epoch 10/12
1048/1050 [============================>.] - ETA: 0s - loss: 0.5413 - acc: 0.7424 - precision: 0.7402 - recall: 0.7465
Epoch 10: val_acc did not improve from 0.73722
1050/1050 [==============================] - 17s 16ms/step - loss: 0.5409 - acc: 0.7426 - precision: 0.7407 - recall: 0.7467 - val_loss: 0.5588 - val_acc: 0.7056 - val_precision: 0.6719 - val_recall: 0.8033 - lr: 0.0010
Epoch 11/12
1046/1050 [============================>.] - ETA: 0s - loss: 0.5371 - acc: 0.7439 - precision: 0.7437 - recall: 0.7435
Epoch 11: val_acc did not improve from 0.73722
1050/1050 [==============================] - 18s 17ms/step - loss: 0.5371 - acc: 0.7436 - precision: 0.7438 - recall: 0.7431 - val_loss: 0.5641 - val_acc: 0.7156 - val_precision: 0.6628 - val_recall: 0.8778 - lr: 0.0010
Epoch 12/12
1045/1050 [============================>.] - ETA: 0s - loss: 0.5356 - acc: 0.7440 - precision: 0.7432 - recall: 0.7461
Epoch 12: val_acc did not improve from 0.73722
1050/1050 [==============================] - 17s 16ms/step - loss: 0.5349 - acc: 0.7446 - precision: 0.7439 - recall: 0.7462 - val_loss: 0.5456 - val_acc: 0.7239 - val_precision: 0.7114 - val_recall: 0.7533 - lr: 0.0010
57/57 [==============================] - 0s 3ms/step
--------------------------------------------------------------------------------
Classification Matrix
--------------------------------------------------------------------------------
precision recall f1-score support
Normal (Class 0) 0.76 0.65 0.70 900
Pneumonia (Class 1) 0.70 0.79 0.74 900
accuracy 0.72 1800
macro avg 0.73 0.72 0.72 1800
weighted avg 0.73 0.72 0.72 1800
--------------------------------------------------------------------------------
<Figure size 640x480 with 0 Axes>
model_3 = create_model_3()
history_3 = fit_model(model_3)
evaluate_model_perf(history_3, model_3, 'CNN_Leaky_ReLU')
save_pickle(model_3, '/kaggle/working/model_3.pkl')
Model: "sequential_5"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_15 (Conv2D) (None, 30, 30, 32) 320
max_pooling2d_15 (MaxPoolin (None, 15, 15, 32) 0
g2D)
conv2d_16 (Conv2D) (None, 13, 13, 64) 18496
max_pooling2d_16 (MaxPoolin (None, 6, 6, 64) 0
g2D)
conv2d_17 (Conv2D) (None, 4, 4, 128) 73856
max_pooling2d_17 (MaxPoolin (None, 2, 2, 128) 0
g2D)
flatten_5 (Flatten) (None, 512) 0
dense_10 (Dense) (None, 512) 262656
dropout (Dropout) (None, 512) 0
dense_11 (Dense) (None, 1) 513
=================================================================
Total params: 355,841
Trainable params: 355,841
Non-trainable params: 0
_________________________________________________________________
Epoch 1/12
1044/1050 [============================>.] - ETA: 0s - loss: 0.6046 - acc: 0.6709 - precision: 0.6759 - recall: 0.6935
Epoch 1: val_acc did not improve from 0.73722
1050/1050 [==============================] - 20s 16ms/step - loss: 0.6048 - acc: 0.6710 - precision: 0.6754 - recall: 0.6943 - val_loss: 0.5731 - val_acc: 0.7161 - val_precision: 0.6975 - val_recall: 0.7633 - lr: 0.0010
Epoch 2/12
1043/1050 [============================>.] - ETA: 0s - loss: 0.5732 - acc: 0.7040 - precision: 0.7038 - recall: 0.7048
Epoch 2: val_acc did not improve from 0.73722
1050/1050 [==============================] - 17s 16ms/step - loss: 0.5734 - acc: 0.7037 - precision: 0.7035 - recall: 0.7040 - val_loss: 0.5586 - val_acc: 0.7150 - val_precision: 0.7268 - val_recall: 0.6889 - lr: 0.0010
Epoch 3/12
1043/1050 [============================>.] - ETA: 0s - loss: 0.5658 - acc: 0.7081 - precision: 0.7094 - recall: 0.7036
Epoch 3: val_acc did not improve from 0.73722
1050/1050 [==============================] - 16s 15ms/step - loss: 0.5657 - acc: 0.7077 - precision: 0.7096 - recall: 0.7033 - val_loss: 0.5470 - val_acc: 0.7233 - val_precision: 0.7228 - val_recall: 0.7244 - lr: 0.0010
Epoch 4/12
1045/1050 [============================>.] - ETA: 0s - loss: 0.5586 - acc: 0.7222 - precision: 0.7247 - recall: 0.7174
Epoch 4: val_acc did not improve from 0.73722
1050/1050 [==============================] - 16s 15ms/step - loss: 0.5584 - acc: 0.7226 - precision: 0.7247 - recall: 0.7181 - val_loss: 0.5560 - val_acc: 0.7206 - val_precision: 0.7436 - val_recall: 0.6733 - lr: 0.0010
Epoch 5/12
1050/1050 [==============================] - ETA: 0s - loss: 0.5578 - acc: 0.7207 - precision: 0.7198 - recall: 0.7229
Epoch 5: val_acc did not improve from 0.73722
1050/1050 [==============================] - 16s 15ms/step - loss: 0.5578 - acc: 0.7207 - precision: 0.7198 - recall: 0.7229 - val_loss: 0.5414 - val_acc: 0.7272 - val_precision: 0.7485 - val_recall: 0.6844 - lr: 0.0010
Epoch 6/12
1045/1050 [============================>.] - ETA: 0s - loss: 0.5597 - acc: 0.7206 - precision: 0.7255 - recall: 0.7106
Epoch 6: val_acc did not improve from 0.73722
1050/1050 [==============================] - 16s 15ms/step - loss: 0.5597 - acc: 0.7207 - precision: 0.7250 - recall: 0.7112 - val_loss: 0.5588 - val_acc: 0.7172 - val_precision: 0.6809 - val_recall: 0.8178 - lr: 0.0010
Epoch 7/12
1047/1050 [============================>.] - ETA: 0s - loss: 0.5526 - acc: 0.7228 - precision: 0.7251 - recall: 0.7175
Epoch 7: val_acc did not improve from 0.73722
1050/1050 [==============================] - 17s 16ms/step - loss: 0.5531 - acc: 0.7226 - precision: 0.7250 - recall: 0.7174 - val_loss: 0.5625 - val_acc: 0.7211 - val_precision: 0.7704 - val_recall: 0.6300 - lr: 0.0010
Epoch 8/12
1049/1050 [============================>.] - ETA: 0s - loss: 0.5555 - acc: 0.7252 - precision: 0.7236 - recall: 0.7287
Epoch 8: val_acc did not improve from 0.73722
1050/1050 [==============================] - 16s 15ms/step - loss: 0.5555 - acc: 0.7251 - precision: 0.7236 - recall: 0.7286 - val_loss: 0.5569 - val_acc: 0.7222 - val_precision: 0.7762 - val_recall: 0.6244 - lr: 0.0010
Epoch 9/12
1047/1050 [============================>.] - ETA: 0s - loss: 0.5466 - acc: 0.7266 - precision: 0.7256 - recall: 0.7297
Epoch 9: val_acc did not improve from 0.73722
1050/1050 [==============================] - 16s 15ms/step - loss: 0.5468 - acc: 0.7264 - precision: 0.7248 - recall: 0.7300 - val_loss: 0.5464 - val_acc: 0.7289 - val_precision: 0.6969 - val_recall: 0.8100 - lr: 0.0010
Epoch 10/12
1049/1050 [============================>.] - ETA: 0s - loss: 0.5474 - acc: 0.7307 - precision: 0.7311 - recall: 0.7300
Epoch 10: val_acc did not improve from 0.73722
1050/1050 [==============================] - 17s 16ms/step - loss: 0.5472 - acc: 0.7307 - precision: 0.7312 - recall: 0.7298 - val_loss: 0.5607 - val_acc: 0.7117 - val_precision: 0.7900 - val_recall: 0.5767 - lr: 0.0010
57/57 [==============================] - 0s 2ms/step
--------------------------------------------------------------------------------
Classification Matrix
--------------------------------------------------------------------------------
precision recall f1-score support
Normal (Class 0) 0.71 0.82 0.76 900
Pneumonia (Class 1) 0.79 0.67 0.72 900
accuracy 0.74 1800
macro avg 0.75 0.74 0.74 1800
weighted avg 0.75 0.74 0.74 1800
--------------------------------------------------------------------------------
<Figure size 640x480 with 0 Axes>
model_4 = create_model_4()
history_4 = fit_model(model_4)
evaluate_model_perf(history_4, model_4, 'CNN_Adam_Opt')
save_pickle(model_4, '/kaggle/working/model_4.pkl')
Model: "sequential_6"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_18 (Conv2D) (None, 30, 30, 32) 320
max_pooling2d_18 (MaxPoolin (None, 15, 15, 32) 0
g2D)
conv2d_19 (Conv2D) (None, 13, 13, 64) 18496
max_pooling2d_19 (MaxPoolin (None, 6, 6, 64) 0
g2D)
conv2d_20 (Conv2D) (None, 4, 4, 128) 73856
max_pooling2d_20 (MaxPoolin (None, 2, 2, 128) 0
g2D)
flatten_6 (Flatten) (None, 512) 0
dense_12 (Dense) (None, 512) 262656
dropout_1 (Dropout) (None, 512) 0
dense_13 (Dense) (None, 1) 513
=================================================================
Total params: 355,841
Trainable params: 355,841
Non-trainable params: 0
_________________________________________________________________
Epoch 1/12
1049/1050 [============================>.] - ETA: 0s - loss: 0.6045 - acc: 0.6739 - precision: 0.6925 - recall: 0.6493
Epoch 1: val_acc did not improve from 0.73722
1050/1050 [==============================] - 19s 15ms/step - loss: 0.6048 - acc: 0.6736 - precision: 0.6922 - recall: 0.6492 - val_loss: 0.5612 - val_acc: 0.7128 - val_precision: 0.7189 - val_recall: 0.6989 - lr: 0.0010
Epoch 2/12
1049/1050 [============================>.] - ETA: 0s - loss: 0.5714 - acc: 0.7084 - precision: 0.7086 - recall: 0.7077
Epoch 2: val_acc did not improve from 0.73722
1050/1050 [==============================] - 17s 16ms/step - loss: 0.5712 - acc: 0.7087 - precision: 0.7089 - recall: 0.7081 - val_loss: 0.5638 - val_acc: 0.7172 - val_precision: 0.6885 - val_recall: 0.7933 - lr: 0.0010
Epoch 3/12
1049/1050 [============================>.] - ETA: 0s - loss: 0.5627 - acc: 0.7150 - precision: 0.7145 - recall: 0.7162
Epoch 3: val_acc did not improve from 0.73722
1050/1050 [==============================] - 16s 15ms/step - loss: 0.5627 - acc: 0.7149 - precision: 0.7144 - recall: 0.7160 - val_loss: 0.6955 - val_acc: 0.6478 - val_precision: 0.7969 - val_recall: 0.3967 - lr: 0.0010
Epoch 4/12
1043/1050 [============================>.] - ETA: 0s - loss: 0.5653 - acc: 0.7096 - precision: 0.7131 - recall: 0.7013
Epoch 4: val_acc did not improve from 0.73722
1050/1050 [==============================] - 16s 15ms/step - loss: 0.5661 - acc: 0.7094 - precision: 0.7132 - recall: 0.7005 - val_loss: 0.5536 - val_acc: 0.7228 - val_precision: 0.7424 - val_recall: 0.6822 - lr: 0.0010
Epoch 5/12
1049/1050 [============================>.] - ETA: 0s - loss: 0.5578 - acc: 0.7216 - precision: 0.7203 - recall: 0.7244
Epoch 5: val_acc did not improve from 0.73722
1050/1050 [==============================] - 17s 16ms/step - loss: 0.5578 - acc: 0.7215 - precision: 0.7202 - recall: 0.7245 - val_loss: 0.5473 - val_acc: 0.7294 - val_precision: 0.7209 - val_recall: 0.7489 - lr: 0.0010
Epoch 6/12
1046/1050 [============================>.] - ETA: 0s - loss: 0.5551 - acc: 0.7216 - precision: 0.7241 - recall: 0.7148
Epoch 6: val_acc did not improve from 0.73722
1050/1050 [==============================] - 16s 15ms/step - loss: 0.5555 - acc: 0.7208 - precision: 0.7242 - recall: 0.7133 - val_loss: 0.5571 - val_acc: 0.7206 - val_precision: 0.7701 - val_recall: 0.6289 - lr: 0.0010
Epoch 7/12
1042/1050 [============================>.] - ETA: 0s - loss: 0.5521 - acc: 0.7234 - precision: 0.7255 - recall: 0.7186
Epoch 7: val_acc did not improve from 0.73722
1050/1050 [==============================] - 17s 16ms/step - loss: 0.5524 - acc: 0.7230 - precision: 0.7247 - recall: 0.7190 - val_loss: 0.5483 - val_acc: 0.7217 - val_precision: 0.7239 - val_recall: 0.7167 - lr: 0.0010
Epoch 8/12
1047/1050 [============================>.] - ETA: 0s - loss: 0.5475 - acc: 0.7270 - precision: 0.7237 - recall: 0.7345
Epoch 8: val_acc did not improve from 0.73722
1050/1050 [==============================] - 16s 15ms/step - loss: 0.5473 - acc: 0.7270 - precision: 0.7238 - recall: 0.7343 - val_loss: 0.5560 - val_acc: 0.7139 - val_precision: 0.7556 - val_recall: 0.6322 - lr: 0.0010
Epoch 9/12
1049/1050 [============================>.] - ETA: 0s - loss: 0.5481 - acc: 0.7299 - precision: 0.7295 - recall: 0.7307
Epoch 9: val_acc did not improve from 0.73722
1050/1050 [==============================] - 16s 16ms/step - loss: 0.5480 - acc: 0.7300 - precision: 0.7297 - recall: 0.7307 - val_loss: 0.5425 - val_acc: 0.7306 - val_precision: 0.7150 - val_recall: 0.7667 - lr: 0.0010
Epoch 10/12
1050/1050 [==============================] - ETA: 0s - loss: 0.5467 - acc: 0.7281 - precision: 0.7303 - recall: 0.7233
Epoch 10: val_acc improved from 0.73722 to 0.74167, saving model to /kaggle/working/weights.hdf5
1050/1050 [==============================] - 17s 16ms/step - loss: 0.5467 - acc: 0.7281 - precision: 0.7303 - recall: 0.7233 - val_loss: 0.5303 - val_acc: 0.7417 - val_precision: 0.7574 - val_recall: 0.7111 - lr: 0.0010
Epoch 11/12
1047/1050 [============================>.] - ETA: 0s - loss: 0.5441 - acc: 0.7315 - precision: 0.7310 - recall: 0.7309
Epoch 11: val_acc did not improve from 0.74167
1050/1050 [==============================] - 16s 15ms/step - loss: 0.5438 - acc: 0.7317 - precision: 0.7320 - recall: 0.7310 - val_loss: 0.5467 - val_acc: 0.7367 - val_precision: 0.7710 - val_recall: 0.6733 - lr: 0.0010
Epoch 12/12
1049/1050 [============================>.] - ETA: 0s - loss: 0.5395 - acc: 0.7303 - precision: 0.7292 - recall: 0.7328
Epoch 12: val_acc improved from 0.74167 to 0.74333, saving model to /kaggle/working/weights.hdf5
1050/1050 [==============================] - 16s 15ms/step - loss: 0.5394 - acc: 0.7305 - precision: 0.7293 - recall: 0.7331 - val_loss: 0.5387 - val_acc: 0.7433 - val_precision: 0.7355 - val_recall: 0.7600 - lr: 0.0010
57/57 [==============================] - 0s 2ms/step
--------------------------------------------------------------------------------
Classification Matrix
--------------------------------------------------------------------------------
precision recall f1-score support
Normal (Class 0) 0.76 0.75 0.75 900
Pneumonia (Class 1) 0.75 0.76 0.76 900
accuracy 0.75 1800
macro avg 0.75 0.75 0.75 1800
weighted avg 0.75 0.75 0.75 1800
--------------------------------------------------------------------------------
<Figure size 640x480 with 0 Axes>
display_ROC_comparision()
57/57 [==============================] - 0s 2ms/step 57/57 [==============================] - 0s 2ms/step 57/57 [==============================] - 0s 2ms/step 57/57 [==============================] - 0s 2ms/step
display_model_matrix()
--------------------------------------------------------------------------------
Model Performance Comparision Matrix
--------------------------------------------------------------------------------
Model Accuracy Precision Recall F1 Score
3 CNN_Adam_Opt 75.388889 75.394187 75.388889 75.387605
2 CNN_Leaky_ReLU 74.333333 74.901959 74.333333 74.185970
0 Basic_CNN_Model 74.111111 74.163734 74.111111 74.097008
1 CNN Model_Batch_Norm 72.333333 72.794399 72.333333 72.192718
--------------------------------------------------------------------------------
Based on the provided classification matrices and performance metrics, let's compare the four models for pneumonia detection and draw some conclusions:
Model 1:
Accuracy: 74% Precision (Class 1): 75% Recall (Class 1): 72% F1-score (Class 1): 73%
Model 2:
Accuracy: 73% Precision (Class 1): 70% Recall (Class 1): 79% F1-score (Class 1): 74%
Model 3:
Accuracy: 75% Precision (Class 1): 79% Recall (Class 1): 67% F1-score (Class 1): 72%
Model 4:
Accuracy: 75% Precision (Class 1): 75% Recall (Class 1): 76% F1-score (Class 1): 76%
Comparison and Inferences:
Model 1 vs. Model 2:
Model 1 has a slightly higher accuracy, precision for class 1 compared to Model 2. Model 2 performs slightly better in correctly identifying positive cases (pneumonia cases) due to higher recall for class 1. Model 2 has a lower precision, indicating that it has more false positives compared to Model 1.
Model 2 vs. Model 3:
Model 3 has slightly better accuracy and precision for class 1 than Model 2. Model 2, however, has higher recall for class 1, indicating it is better at capturing actual positive cases.
Model 3 vs. Model 4:
Model 4 has higher recall, and F1-score for class 1 compared to Model 3. Model 3 has slightly higher precision but lower performance in correctly identifying positive cases (lower recall).
Conclusion:
Among the four models, Model 4 seems to be the best performer for pneumonia detection based on its overall balanced performance across various metrics. It has a good balance between precision and recall for class 1, which indicates it can effectively detect pneumonia cases while minimizing false positives. Model 3 has the highest precision for class 1, but its recall is the least. This means that Model 3 may have fewer false positives, but it could potentially miss some positive cases.
Model 1 and Model 4 exhibit similar performance, with Model 4 having slightly better recall and better F1-score for the same class.
Overall, the choice of the "best" model depends on the specific trade-off between false positives and false negatives that is acceptable in your application.
For the current problem statement, Model 4 seems to be the best choice for further use.
Hyperparameter tuning or optimization is important in any machine learning model training activity. The hyperparameters of a model cannot be determined from the given datasets through the learning process. However, they are very crucial to control the learning process itself. These hyperparameters originate from the mathematical formulation of machine learning models. For example, the weights learned while training a linear regression model are parameters, but the learning rate in gradient descent is a hyperparameter. The performance of a model on a dataset significantly depends on the proper tuning, i.e., finding the best combination of the model hyperparameters.
Different techniques are available for hyperparameter optimization, such as Grid Search, Randomized Search, Bayesian Optimization, etc.
Grid Search and Randomized Search are two widely used techniques in Hyperparameter Tuning. Grid Search exhaustively searches through every combination of the hyperparameter values specified. In contrast to Grid Search, not all given parameter values are tried out in Randomized Search. Rather a fixed number of parameter settings is sampled from the specified distributions. Sampling without replacement is performed if all parameters are presented as a list. Sampling with replacement is used if at least one parameter is given as a distribution. For each hyperparameter, either a distribution over possible values or a list of discrete values (to be sampled uniformly) can be specified. For the hyperparameters having continuous values, a continuous distribution should be specified to take full advantage of the randomization. The major benefit of this search is a decreased processing time.
HyperParamter Tuning for best model of Milestone 1
We will pick up the best model from Milestone 1 and run Grid Search using the parameters: Optimizer, activation and learning_rate.
The new model will be created using the best parameter from gridSearch results.
# Define your original model creation function
def create_model(optimizer='adam', hidden_units=512, dropout_rate=0.5,
activation='relu', learning_rate=0.001,
weight_init='he_normal'):
if optimizer == 'adam':
opt = Adam(learning_rate=learning_rate)
elif optimizer == 'sgd':
opt = SGD(learning_rate=learning_rate)
else:
raise ValueError('Invalid optimizer')
model = Sequential()
model.add(Conv2D(32, (3, 3), activation=activation, input_shape=(32, 32, 1)))
model.add(MaxPooling2D((2, 2)))
model.add(Conv2D(64, (3, 3), activation=activation))
model.add(MaxPooling2D((2, 2)))
model.add(Conv2D(128, (3, 3), activation=activation))
model.add(MaxPooling2D((2, 2)))
model.add(Flatten())
model.add(Dense(512, activation=LeakyReLU(alpha=0.1)))
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=METRICS)
model.summary()
return model
# Wrap Keras model with KerasClassifier
model = KerasClassifier(build_fn=create_model, epochs=12, verbose=1)
# Define the hyperparameter grid
param_grid = {
'optimizer': ['adam', 'sgd'],
'activation': ['relu' , 'LeakyReLU'],
'learning_rate': [0.0001, 0.001, 0.01],
}
# Create GridSearchCV instance
grid_search = GridSearchCV(estimator=model, param_grid=param_grid, cv=3)
# Fit the grid search
grid_result = grid_search.fit(X_train, y_train)
# Print the best parameters and best score
print("Best: %f using %s" % (grid_result.best_score_, grid_result.best_params_))
means = grid_result.cv_results_['mean_test_score']
stds = grid_result.cv_results_['std_test_score']
params = grid_result.cv_results_['params']
for mean, stdev, param in zip(means, stds, params):
print("%f (%f) with: %r" % (mean, stdev, param))
Model: "sequential_76"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_228 (Conv2D) (None, 30, 30, 32) 320
max_pooling2d_228 (MaxPooli (None, 15, 15, 32) 0
ng2D)
conv2d_229 (Conv2D) (None, 13, 13, 64) 18496
max_pooling2d_229 (MaxPooli (None, 6, 6, 64) 0
ng2D)
conv2d_230 (Conv2D) (None, 4, 4, 128) 73856
max_pooling2d_230 (MaxPooli (None, 2, 2, 128) 0
ng2D)
flatten_76 (Flatten) (None, 512) 0
dense_152 (Dense) (None, 512) 262656
dropout_74 (Dropout) (None, 512) 0
dense_153 (Dense) (None, 1) 513
=================================================================
Total params: 355,841
Trainable params: 355,841
Non-trainable params: 0
_________________________________________________________________
/tmp/ipykernel_28/416103543.py:28: DeprecationWarning: KerasClassifier is deprecated, use Sci-Keras (https://github.com/adriangb/scikeras) instead. See https://www.adriangb.com/scikeras/stable/migration.html for help migrating. model = KerasClassifier(build_fn=create_model, epochs=12, verbose=1)
Epoch 1/12
175/175 [==============================] - 3s 5ms/step - loss: 0.6003 - acc: 0.6748 - precision: 0.6928 - recall: 0.6858
Epoch 2/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5516 - acc: 0.7307 - precision: 0.7227 - recall: 0.7420
Epoch 3/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5388 - acc: 0.7409 - precision: 0.7345 - recall: 0.7485
Epoch 4/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5313 - acc: 0.7409 - precision: 0.7343 - recall: 0.7488
Epoch 5/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5186 - acc: 0.7452 - precision: 0.7414 - recall: 0.7470
Epoch 6/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5070 - acc: 0.7645 - precision: 0.7611 - recall: 0.7657
Epoch 7/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5021 - acc: 0.7600 - precision: 0.7556 - recall: 0.7632
Epoch 8/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4956 - acc: 0.7593 - precision: 0.7542 - recall: 0.7639
Epoch 9/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4796 - acc: 0.7721 - precision: 0.7708 - recall: 0.7697
Epoch 10/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4693 - acc: 0.7798 - precision: 0.7757 - recall: 0.7827
Epoch 11/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4578 - acc: 0.7879 - precision: 0.7822 - recall: 0.7935
Epoch 12/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4433 - acc: 0.7955 - precision: 0.7873 - recall: 0.8057
88/88 [==============================] - 1s 4ms/step - loss: 0.5357 - acc: 0.7525 - precision: 0.7324 - recall: 0.8072
Model: "sequential_77"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_231 (Conv2D) (None, 30, 30, 32) 320
max_pooling2d_231 (MaxPooli (None, 15, 15, 32) 0
ng2D)
conv2d_232 (Conv2D) (None, 13, 13, 64) 18496
max_pooling2d_232 (MaxPooli (None, 6, 6, 64) 0
ng2D)
conv2d_233 (Conv2D) (None, 4, 4, 128) 73856
max_pooling2d_233 (MaxPooli (None, 2, 2, 128) 0
ng2D)
flatten_77 (Flatten) (None, 512) 0
dense_154 (Dense) (None, 512) 262656
dropout_75 (Dropout) (None, 512) 0
dense_155 (Dense) (None, 1) 513
=================================================================
Total params: 355,841
Trainable params: 355,841
Non-trainable params: 0
_________________________________________________________________
Epoch 1/12
175/175 [==============================] - 3s 4ms/step - loss: 0.5908 - acc: 0.6854 - precision: 0.6987 - recall: 0.7419
Epoch 2/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5506 - acc: 0.7243 - precision: 0.7220 - recall: 0.7378
Epoch 3/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5392 - acc: 0.7366 - precision: 0.7333 - recall: 0.7512
Epoch 4/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5324 - acc: 0.7407 - precision: 0.7342 - recall: 0.7622
Epoch 5/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5267 - acc: 0.7454 - precision: 0.7437 - recall: 0.7558
Epoch 6/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5215 - acc: 0.7529 - precision: 0.7490 - recall: 0.7675
Epoch 7/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5173 - acc: 0.7511 - precision: 0.7421 - recall: 0.7767
Epoch 8/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5067 - acc: 0.7550 - precision: 0.7521 - recall: 0.7675
Epoch 9/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5081 - acc: 0.7529 - precision: 0.7476 - recall: 0.7703
Epoch 10/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4954 - acc: 0.7604 - precision: 0.7545 - recall: 0.7785
Epoch 11/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4835 - acc: 0.7705 - precision: 0.7656 - recall: 0.7859
Epoch 12/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4790 - acc: 0.7684 - precision: 0.7630 - recall: 0.7849
88/88 [==============================] - 1s 3ms/step - loss: 0.5317 - acc: 0.7457 - precision: 0.7028 - recall: 0.8348
Model: "sequential_78"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_234 (Conv2D) (None, 30, 30, 32) 320
max_pooling2d_234 (MaxPooli (None, 15, 15, 32) 0
ng2D)
conv2d_235 (Conv2D) (None, 13, 13, 64) 18496
max_pooling2d_235 (MaxPooli (None, 6, 6, 64) 0
ng2D)
conv2d_236 (Conv2D) (None, 4, 4, 128) 73856
max_pooling2d_236 (MaxPooli (None, 2, 2, 128) 0
ng2D)
flatten_78 (Flatten) (None, 512) 0
dense_156 (Dense) (None, 512) 262656
dropout_76 (Dropout) (None, 512) 0
dense_157 (Dense) (None, 1) 513
=================================================================
Total params: 355,841
Trainable params: 355,841
Non-trainable params: 0
_________________________________________________________________
Epoch 1/12
175/175 [==============================] - 3s 5ms/step - loss: 0.5941 - acc: 0.6829 - precision: 0.6864 - recall: 0.7424
Epoch 2/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5548 - acc: 0.7202 - precision: 0.7129 - recall: 0.7356
Epoch 3/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5410 - acc: 0.7345 - precision: 0.7311 - recall: 0.7403
Epoch 4/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5288 - acc: 0.7414 - precision: 0.7317 - recall: 0.7610
Epoch 5/12
175/175 [==============================] - 1s 7ms/step - loss: 0.5225 - acc: 0.7495 - precision: 0.7423 - recall: 0.7628
Epoch 6/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5129 - acc: 0.7518 - precision: 0.7412 - recall: 0.7725
Epoch 7/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5069 - acc: 0.7564 - precision: 0.7490 - recall: 0.7699
Epoch 8/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4973 - acc: 0.7673 - precision: 0.7597 - recall: 0.7807
Epoch 9/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4871 - acc: 0.7696 - precision: 0.7625 - recall: 0.7821
Epoch 10/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4791 - acc: 0.7759 - precision: 0.7700 - recall: 0.7857
Epoch 11/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4683 - acc: 0.7773 - precision: 0.7699 - recall: 0.7900
Epoch 12/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4557 - acc: 0.7850 - precision: 0.7808 - recall: 0.7914
88/88 [==============================] - 1s 4ms/step - loss: 0.5489 - acc: 0.7389 - precision: 0.7157 - recall: 0.7957
Model: "sequential_79"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_237 (Conv2D) (None, 30, 30, 32) 320
max_pooling2d_237 (MaxPooli (None, 15, 15, 32) 0
ng2D)
conv2d_238 (Conv2D) (None, 13, 13, 64) 18496
max_pooling2d_238 (MaxPooli (None, 6, 6, 64) 0
ng2D)
conv2d_239 (Conv2D) (None, 4, 4, 128) 73856
max_pooling2d_239 (MaxPooli (None, 2, 2, 128) 0
ng2D)
flatten_79 (Flatten) (None, 512) 0
dense_158 (Dense) (None, 512) 262656
dropout_77 (Dropout) (None, 512) 0
dense_159 (Dense) (None, 1) 513
=================================================================
Total params: 355,841
Trainable params: 355,841
Non-trainable params: 0
_________________________________________________________________
Epoch 1/12
175/175 [==============================] - 3s 4ms/step - loss: 0.6022 - acc: 0.6711 - precision: 0.6882 - recall: 0.7039
Epoch 2/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5479 - acc: 0.7280 - precision: 0.7219 - recall: 0.7352
Epoch 3/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5371 - acc: 0.7389 - precision: 0.7315 - recall: 0.7488
Epoch 4/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5315 - acc: 0.7354 - precision: 0.7289 - recall: 0.7431
Epoch 5/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5184 - acc: 0.7489 - precision: 0.7442 - recall: 0.7528
Epoch 6/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5096 - acc: 0.7564 - precision: 0.7531 - recall: 0.7575
Epoch 7/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5047 - acc: 0.7577 - precision: 0.7548 - recall: 0.7578
Epoch 8/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5044 - acc: 0.7525 - precision: 0.7460 - recall: 0.7600
Epoch 9/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4809 - acc: 0.7718 - precision: 0.7655 - recall: 0.7787
Epoch 10/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4706 - acc: 0.7748 - precision: 0.7718 - recall: 0.7755
Epoch 11/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4558 - acc: 0.7859 - precision: 0.7819 - recall: 0.7884
Epoch 12/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4463 - acc: 0.7927 - precision: 0.7889 - recall: 0.7949
88/88 [==============================] - 1s 3ms/step - loss: 0.5486 - acc: 0.7425 - precision: 0.7210 - recall: 0.8037
Model: "sequential_80"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_240 (Conv2D) (None, 30, 30, 32) 320
max_pooling2d_240 (MaxPooli (None, 15, 15, 32) 0
ng2D)
conv2d_241 (Conv2D) (None, 13, 13, 64) 18496
max_pooling2d_241 (MaxPooli (None, 6, 6, 64) 0
ng2D)
conv2d_242 (Conv2D) (None, 4, 4, 128) 73856
max_pooling2d_242 (MaxPooli (None, 2, 2, 128) 0
ng2D)
flatten_80 (Flatten) (None, 512) 0
dense_160 (Dense) (None, 512) 262656
dropout_78 (Dropout) (None, 512) 0
dense_161 (Dense) (None, 1) 513
=================================================================
Total params: 355,841
Trainable params: 355,841
Non-trainable params: 0
_________________________________________________________________
Epoch 1/12
175/175 [==============================] - 3s 5ms/step - loss: 0.5881 - acc: 0.6871 - precision: 0.6982 - recall: 0.7358
Epoch 2/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5536 - acc: 0.7211 - precision: 0.7181 - recall: 0.7364
Epoch 3/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5390 - acc: 0.7366 - precision: 0.7329 - recall: 0.7523
Epoch 4/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5338 - acc: 0.7427 - precision: 0.7366 - recall: 0.7629
Epoch 5/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5283 - acc: 0.7396 - precision: 0.7359 - recall: 0.7551
Epoch 6/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5237 - acc: 0.7541 - precision: 0.7525 - recall: 0.7640
Epoch 7/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5162 - acc: 0.7548 - precision: 0.7506 - recall: 0.7700
Epoch 8/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5087 - acc: 0.7602 - precision: 0.7545 - recall: 0.7778
Epoch 9/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5016 - acc: 0.7620 - precision: 0.7579 - recall: 0.7764
Epoch 10/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4952 - acc: 0.7688 - precision: 0.7630 - recall: 0.7859
Epoch 11/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4844 - acc: 0.7696 - precision: 0.7639 - recall: 0.7866
Epoch 12/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4782 - acc: 0.7764 - precision: 0.7690 - recall: 0.7962
88/88 [==============================] - 1s 3ms/step - loss: 0.5121 - acc: 0.7511 - precision: 0.7320 - recall: 0.7773
Model: "sequential_81"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_243 (Conv2D) (None, 30, 30, 32) 320
max_pooling2d_243 (MaxPooli (None, 15, 15, 32) 0
ng2D)
conv2d_244 (Conv2D) (None, 13, 13, 64) 18496
max_pooling2d_244 (MaxPooli (None, 6, 6, 64) 0
ng2D)
conv2d_245 (Conv2D) (None, 4, 4, 128) 73856
max_pooling2d_245 (MaxPooli (None, 2, 2, 128) 0
ng2D)
flatten_81 (Flatten) (None, 512) 0
dense_162 (Dense) (None, 512) 262656
dropout_79 (Dropout) (None, 512) 0
dense_163 (Dense) (None, 1) 513
=================================================================
Total params: 355,841
Trainable params: 355,841
Non-trainable params: 0
_________________________________________________________________
Epoch 1/12
175/175 [==============================] - 3s 5ms/step - loss: 0.6011 - acc: 0.6779 - precision: 0.6924 - recall: 0.7198
Epoch 2/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5557 - acc: 0.7180 - precision: 0.7101 - recall: 0.7352
Epoch 3/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5418 - acc: 0.7273 - precision: 0.7200 - recall: 0.7424
Epoch 4/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5275 - acc: 0.7448 - precision: 0.7363 - recall: 0.7614
Epoch 5/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5216 - acc: 0.7496 - precision: 0.7441 - recall: 0.7596
Epoch 6/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5152 - acc: 0.7491 - precision: 0.7390 - recall: 0.7689
Epoch 7/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5102 - acc: 0.7552 - precision: 0.7505 - recall: 0.7631
Epoch 8/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4997 - acc: 0.7636 - precision: 0.7571 - recall: 0.7750
Epoch 9/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4926 - acc: 0.7598 - precision: 0.7535 - recall: 0.7710
Epoch 10/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4808 - acc: 0.7721 - precision: 0.7662 - recall: 0.7821
Epoch 11/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4729 - acc: 0.7750 - precision: 0.7698 - recall: 0.7835
Epoch 12/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4638 - acc: 0.7862 - precision: 0.7817 - recall: 0.7932
88/88 [==============================] - 1s 3ms/step - loss: 0.5266 - acc: 0.7461 - precision: 0.7496 - recall: 0.7416
Model: "sequential_82"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_246 (Conv2D) (None, 30, 30, 32) 320
max_pooling2d_246 (MaxPooli (None, 15, 15, 32) 0
ng2D)
conv2d_247 (Conv2D) (None, 13, 13, 64) 18496
max_pooling2d_247 (MaxPooli (None, 6, 6, 64) 0
ng2D)
conv2d_248 (Conv2D) (None, 4, 4, 128) 73856
max_pooling2d_248 (MaxPooli (None, 2, 2, 128) 0
ng2D)
flatten_82 (Flatten) (None, 512) 0
dense_164 (Dense) (None, 512) 262656
dropout_80 (Dropout) (None, 512) 0
dense_165 (Dense) (None, 1) 513
=================================================================
Total params: 355,841
Trainable params: 355,841
Non-trainable params: 0
_________________________________________________________________
Epoch 1/12
175/175 [==============================] - 3s 5ms/step - loss: 0.6022 - acc: 0.6723 - precision: 0.6983 - recall: 0.6893
Epoch 2/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5489 - acc: 0.7291 - precision: 0.7206 - recall: 0.7416
Epoch 3/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5393 - acc: 0.7364 - precision: 0.7276 - recall: 0.7496
Epoch 4/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5335 - acc: 0.7325 - precision: 0.7264 - recall: 0.7395
Epoch 5/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5221 - acc: 0.7432 - precision: 0.7362 - recall: 0.7521
Epoch 6/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5128 - acc: 0.7527 - precision: 0.7456 - recall: 0.7614
Epoch 7/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5054 - acc: 0.7579 - precision: 0.7529 - recall: 0.7621
Epoch 8/12
175/175 [==============================] - 1s 6ms/step - loss: 0.4960 - acc: 0.7561 - precision: 0.7492 - recall: 0.7643
Epoch 9/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4830 - acc: 0.7723 - precision: 0.7663 - recall: 0.7787
Epoch 10/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4739 - acc: 0.7752 - precision: 0.7728 - recall: 0.7747
Epoch 11/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4630 - acc: 0.7857 - precision: 0.7847 - recall: 0.7830
Epoch 12/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4496 - acc: 0.7884 - precision: 0.7853 - recall: 0.7895
88/88 [==============================] - 1s 3ms/step - loss: 0.5385 - acc: 0.7475 - precision: 0.7254 - recall: 0.8086
Model: "sequential_83"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_249 (Conv2D) (None, 30, 30, 32) 320
max_pooling2d_249 (MaxPooli (None, 15, 15, 32) 0
ng2D)
conv2d_250 (Conv2D) (None, 13, 13, 64) 18496
max_pooling2d_250 (MaxPooli (None, 6, 6, 64) 0
ng2D)
conv2d_251 (Conv2D) (None, 4, 4, 128) 73856
max_pooling2d_251 (MaxPooli (None, 2, 2, 128) 0
ng2D)
flatten_83 (Flatten) (None, 512) 0
dense_166 (Dense) (None, 512) 262656
dropout_81 (Dropout) (None, 512) 0
dense_167 (Dense) (None, 1) 513
=================================================================
Total params: 355,841
Trainable params: 355,841
Non-trainable params: 0
_________________________________________________________________
Epoch 1/12
175/175 [==============================] - 3s 4ms/step - loss: 0.5898 - acc: 0.6889 - precision: 0.7032 - recall: 0.7325
Epoch 2/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5506 - acc: 0.7273 - precision: 0.7250 - recall: 0.7406
Epoch 3/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5368 - acc: 0.7411 - precision: 0.7361 - recall: 0.7590
Epoch 4/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5316 - acc: 0.7421 - precision: 0.7375 - recall: 0.7594
Epoch 5/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5222 - acc: 0.7461 - precision: 0.7426 - recall: 0.7604
Epoch 6/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5151 - acc: 0.7534 - precision: 0.7482 - recall: 0.7707
Epoch 7/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5092 - acc: 0.7555 - precision: 0.7499 - recall: 0.7735
Epoch 8/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5008 - acc: 0.7625 - precision: 0.7590 - recall: 0.7757
Epoch 9/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4928 - acc: 0.7677 - precision: 0.7616 - recall: 0.7856
Epoch 10/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4812 - acc: 0.7779 - precision: 0.7713 - recall: 0.7958
Epoch 11/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4697 - acc: 0.7823 - precision: 0.7770 - recall: 0.7976
Epoch 12/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4591 - acc: 0.7861 - precision: 0.7817 - recall: 0.7994
88/88 [==============================] - 1s 3ms/step - loss: 0.5112 - acc: 0.7543 - precision: 0.7311 - recall: 0.7897
Model: "sequential_84"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_252 (Conv2D) (None, 30, 30, 32) 320
max_pooling2d_252 (MaxPooli (None, 15, 15, 32) 0
ng2D)
conv2d_253 (Conv2D) (None, 13, 13, 64) 18496
max_pooling2d_253 (MaxPooli (None, 6, 6, 64) 0
ng2D)
conv2d_254 (Conv2D) (None, 4, 4, 128) 73856
max_pooling2d_254 (MaxPooli (None, 2, 2, 128) 0
ng2D)
flatten_84 (Flatten) (None, 512) 0
dense_168 (Dense) (None, 512) 262656
dropout_82 (Dropout) (None, 512) 0
dense_169 (Dense) (None, 1) 513
=================================================================
Total params: 355,841
Trainable params: 355,841
Non-trainable params: 0
_________________________________________________________________
Epoch 1/12
175/175 [==============================] - 3s 5ms/step - loss: 0.5984 - acc: 0.6764 - precision: 0.6930 - recall: 0.7186
Epoch 2/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5518 - acc: 0.7230 - precision: 0.7154 - recall: 0.7392
Epoch 3/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5393 - acc: 0.7305 - precision: 0.7242 - recall: 0.7431
Epoch 4/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5262 - acc: 0.7427 - precision: 0.7357 - recall: 0.7560
Epoch 5/12
175/175 [==============================] - 1s 6ms/step - loss: 0.5186 - acc: 0.7539 - precision: 0.7490 - recall: 0.7624
Epoch 6/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5122 - acc: 0.7493 - precision: 0.7394 - recall: 0.7685
Epoch 7/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5063 - acc: 0.7588 - precision: 0.7530 - recall: 0.7689
Epoch 8/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4993 - acc: 0.7600 - precision: 0.7506 - recall: 0.7775
Epoch 9/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4922 - acc: 0.7655 - precision: 0.7571 - recall: 0.7807
Epoch 10/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4766 - acc: 0.7743 - precision: 0.7685 - recall: 0.7839
Epoch 11/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4734 - acc: 0.7780 - precision: 0.7696 - recall: 0.7925
Epoch 12/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4634 - acc: 0.7809 - precision: 0.7722 - recall: 0.7957
88/88 [==============================] - 1s 5ms/step - loss: 0.5463 - acc: 0.7346 - precision: 0.7108 - recall: 0.7943
Model: "sequential_85"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_255 (Conv2D) (None, 30, 30, 32) 320
max_pooling2d_255 (MaxPooli (None, 15, 15, 32) 0
ng2D)
conv2d_256 (Conv2D) (None, 13, 13, 64) 18496
max_pooling2d_256 (MaxPooli (None, 6, 6, 64) 0
ng2D)
conv2d_257 (Conv2D) (None, 4, 4, 128) 73856
max_pooling2d_257 (MaxPooli (None, 2, 2, 128) 0
ng2D)
flatten_85 (Flatten) (None, 512) 0
dense_170 (Dense) (None, 512) 262656
dropout_83 (Dropout) (None, 512) 0
dense_171 (Dense) (None, 1) 513
=================================================================
Total params: 355,841
Trainable params: 355,841
Non-trainable params: 0
_________________________________________________________________
Epoch 1/12
175/175 [==============================] - 3s 4ms/step - loss: 0.6161 - acc: 0.6539 - precision: 0.6742 - recall: 0.6953
Epoch 2/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5525 - acc: 0.7225 - precision: 0.7139 - recall: 0.7355
Epoch 3/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5392 - acc: 0.7354 - precision: 0.7284 - recall: 0.7442
Epoch 4/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5392 - acc: 0.7307 - precision: 0.7250 - recall: 0.7370
Epoch 5/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5227 - acc: 0.7430 - precision: 0.7389 - recall: 0.7456
Epoch 6/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5151 - acc: 0.7484 - precision: 0.7409 - recall: 0.7582
Epoch 7/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5123 - acc: 0.7513 - precision: 0.7442 - recall: 0.7600
Epoch 8/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5067 - acc: 0.7475 - precision: 0.7397 - recall: 0.7578
Epoch 9/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4930 - acc: 0.7605 - precision: 0.7557 - recall: 0.7647
Epoch 10/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4844 - acc: 0.7684 - precision: 0.7658 - recall: 0.7683
Epoch 11/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4679 - acc: 0.7763 - precision: 0.7710 - recall: 0.7812
Epoch 12/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4620 - acc: 0.7859 - precision: 0.7805 - recall: 0.7909
88/88 [==============================] - 1s 3ms/step - loss: 0.5265 - acc: 0.7579 - precision: 0.7386 - recall: 0.8093
Model: "sequential_86"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_258 (Conv2D) (None, 30, 30, 32) 320
max_pooling2d_258 (MaxPooli (None, 15, 15, 32) 0
ng2D)
conv2d_259 (Conv2D) (None, 13, 13, 64) 18496
max_pooling2d_259 (MaxPooli (None, 6, 6, 64) 0
ng2D)
conv2d_260 (Conv2D) (None, 4, 4, 128) 73856
max_pooling2d_260 (MaxPooli (None, 2, 2, 128) 0
ng2D)
flatten_86 (Flatten) (None, 512) 0
dense_172 (Dense) (None, 512) 262656
dropout_84 (Dropout) (None, 512) 0
dense_173 (Dense) (None, 1) 513
=================================================================
Total params: 355,841
Trainable params: 355,841
Non-trainable params: 0
_________________________________________________________________
Epoch 1/12
175/175 [==============================] - 3s 6ms/step - loss: 0.5872 - acc: 0.6925 - precision: 0.7088 - recall: 0.7382
Epoch 2/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5496 - acc: 0.7284 - precision: 0.7251 - recall: 0.7438
Epoch 3/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5366 - acc: 0.7423 - precision: 0.7361 - recall: 0.7629
Epoch 4/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5280 - acc: 0.7434 - precision: 0.7383 - recall: 0.7615
Epoch 5/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5210 - acc: 0.7480 - precision: 0.7476 - recall: 0.7558
Epoch 6/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5158 - acc: 0.7568 - precision: 0.7491 - recall: 0.7788
Epoch 7/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5095 - acc: 0.7559 - precision: 0.7496 - recall: 0.7753
Epoch 8/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5024 - acc: 0.7627 - precision: 0.7559 - recall: 0.7824
Epoch 9/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4924 - acc: 0.7661 - precision: 0.7616 - recall: 0.7810
Epoch 10/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4860 - acc: 0.7688 - precision: 0.7605 - recall: 0.7909
Epoch 11/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4709 - acc: 0.7818 - precision: 0.7785 - recall: 0.7933
Epoch 12/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4620 - acc: 0.7854 - precision: 0.7790 - recall: 0.8022
88/88 [==============================] - 1s 4ms/step - loss: 0.5303 - acc: 0.7414 - precision: 0.7110 - recall: 0.7969
Model: "sequential_87"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_261 (Conv2D) (None, 30, 30, 32) 320
max_pooling2d_261 (MaxPooli (None, 15, 15, 32) 0
ng2D)
conv2d_262 (Conv2D) (None, 13, 13, 64) 18496
max_pooling2d_262 (MaxPooli (None, 6, 6, 64) 0
ng2D)
conv2d_263 (Conv2D) (None, 4, 4, 128) 73856
max_pooling2d_263 (MaxPooli (None, 2, 2, 128) 0
ng2D)
flatten_87 (Flatten) (None, 512) 0
dense_174 (Dense) (None, 512) 262656
dropout_85 (Dropout) (None, 512) 0
dense_175 (Dense) (None, 1) 513
=================================================================
Total params: 355,841
Trainable params: 355,841
Non-trainable params: 0
_________________________________________________________________
Epoch 1/12
175/175 [==============================] - 3s 4ms/step - loss: 0.6004 - acc: 0.6800 - precision: 0.6886 - recall: 0.7239
Epoch 2/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5536 - acc: 0.7230 - precision: 0.7158 - recall: 0.7381
Epoch 3/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5433 - acc: 0.7277 - precision: 0.7233 - recall: 0.7360
Epoch 4/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5279 - acc: 0.7430 - precision: 0.7361 - recall: 0.7564
Epoch 5/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5288 - acc: 0.7459 - precision: 0.7415 - recall: 0.7535
Epoch 6/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5203 - acc: 0.7464 - precision: 0.7390 - recall: 0.7606
Epoch 7/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5150 - acc: 0.7538 - precision: 0.7484 - recall: 0.7631
Epoch 8/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5069 - acc: 0.7591 - precision: 0.7514 - recall: 0.7732
Epoch 9/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5028 - acc: 0.7621 - precision: 0.7553 - recall: 0.7742
Epoch 10/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4903 - acc: 0.7688 - precision: 0.7611 - recall: 0.7821
Epoch 11/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4871 - acc: 0.7691 - precision: 0.7599 - recall: 0.7857
Epoch 12/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4816 - acc: 0.7736 - precision: 0.7684 - recall: 0.7821
88/88 [==============================] - 1s 4ms/step - loss: 0.5515 - acc: 0.7343 - precision: 0.6975 - recall: 0.8306
Model: "sequential_88"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_264 (Conv2D) (None, 30, 30, 32) 320
max_pooling2d_264 (MaxPooli (None, 15, 15, 32) 0
ng2D)
conv2d_265 (Conv2D) (None, 13, 13, 64) 18496
max_pooling2d_265 (MaxPooli (None, 6, 6, 64) 0
ng2D)
conv2d_266 (Conv2D) (None, 4, 4, 128) 73856
max_pooling2d_266 (MaxPooli (None, 2, 2, 128) 0
ng2D)
flatten_88 (Flatten) (None, 512) 0
dense_176 (Dense) (None, 512) 262656
dropout_86 (Dropout) (None, 512) 0
dense_177 (Dense) (None, 1) 513
=================================================================
Total params: 355,841
Trainable params: 355,841
Non-trainable params: 0
_________________________________________________________________
Epoch 1/12
175/175 [==============================] - 3s 5ms/step - loss: 0.6113 - acc: 0.6580 - precision: 0.6720 - recall: 0.7120
Epoch 2/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5509 - acc: 0.7245 - precision: 0.7144 - recall: 0.7409
Epoch 3/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5410 - acc: 0.7330 - precision: 0.7249 - recall: 0.7445
Epoch 4/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5350 - acc: 0.7336 - precision: 0.7262 - recall: 0.7434
Epoch 5/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5275 - acc: 0.7420 - precision: 0.7382 - recall: 0.7438
Epoch 6/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5171 - acc: 0.7477 - precision: 0.7400 - recall: 0.7578
Epoch 7/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5155 - acc: 0.7500 - precision: 0.7467 - recall: 0.7510
Epoch 8/12
175/175 [==============================] - 1s 6ms/step - loss: 0.5059 - acc: 0.7534 - precision: 0.7468 - recall: 0.7611
Epoch 9/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4943 - acc: 0.7607 - precision: 0.7549 - recall: 0.7668
Epoch 10/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4851 - acc: 0.7659 - precision: 0.7635 - recall: 0.7654
Epoch 11/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4733 - acc: 0.7725 - precision: 0.7681 - recall: 0.7758
Epoch 12/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4643 - acc: 0.7779 - precision: 0.7717 - recall: 0.7845
88/88 [==============================] - 1s 3ms/step - loss: 0.5292 - acc: 0.7468 - precision: 0.7231 - recall: 0.8121
Model: "sequential_89"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_267 (Conv2D) (None, 30, 30, 32) 320
max_pooling2d_267 (MaxPooli (None, 15, 15, 32) 0
ng2D)
conv2d_268 (Conv2D) (None, 13, 13, 64) 18496
max_pooling2d_268 (MaxPooli (None, 6, 6, 64) 0
ng2D)
conv2d_269 (Conv2D) (None, 4, 4, 128) 73856
max_pooling2d_269 (MaxPooli (None, 2, 2, 128) 0
ng2D)
flatten_89 (Flatten) (None, 512) 0
dense_178 (Dense) (None, 512) 262656
dropout_87 (Dropout) (None, 512) 0
dense_179 (Dense) (None, 1) 513
=================================================================
Total params: 355,841
Trainable params: 355,841
Non-trainable params: 0
_________________________________________________________________
Epoch 1/12
175/175 [==============================] - 3s 4ms/step - loss: 0.5955 - acc: 0.6809 - precision: 0.6957 - recall: 0.7328
Epoch 2/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5488 - acc: 0.7248 - precision: 0.7209 - recall: 0.7420
Epoch 3/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5384 - acc: 0.7391 - precision: 0.7358 - recall: 0.7537
Epoch 4/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5297 - acc: 0.7416 - precision: 0.7349 - recall: 0.7633
Epoch 5/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5223 - acc: 0.7432 - precision: 0.7391 - recall: 0.7590
Epoch 6/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5142 - acc: 0.7566 - precision: 0.7504 - recall: 0.7757
Epoch 7/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5091 - acc: 0.7536 - precision: 0.7478 - recall: 0.7721
Epoch 8/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4988 - acc: 0.7650 - precision: 0.7620 - recall: 0.7771
Epoch 9/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4935 - acc: 0.7673 - precision: 0.7598 - recall: 0.7880
Epoch 10/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4820 - acc: 0.7723 - precision: 0.7673 - recall: 0.7877
Epoch 11/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4686 - acc: 0.7786 - precision: 0.7733 - recall: 0.7941
Epoch 12/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4552 - acc: 0.7911 - precision: 0.7875 - recall: 0.8025
88/88 [==============================] - 1s 3ms/step - loss: 0.5356 - acc: 0.7446 - precision: 0.7155 - recall: 0.7962
Model: "sequential_90"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_270 (Conv2D) (None, 30, 30, 32) 320
max_pooling2d_270 (MaxPooli (None, 15, 15, 32) 0
ng2D)
conv2d_271 (Conv2D) (None, 13, 13, 64) 18496
max_pooling2d_271 (MaxPooli (None, 6, 6, 64) 0
ng2D)
conv2d_272 (Conv2D) (None, 4, 4, 128) 73856
max_pooling2d_272 (MaxPooli (None, 2, 2, 128) 0
ng2D)
flatten_90 (Flatten) (None, 512) 0
dense_180 (Dense) (None, 512) 262656
dropout_88 (Dropout) (None, 512) 0
dense_181 (Dense) (None, 1) 513
=================================================================
Total params: 355,841
Trainable params: 355,841
Non-trainable params: 0
_________________________________________________________________
Epoch 1/12
175/175 [==============================] - 3s 5ms/step - loss: 0.5894 - acc: 0.6936 - precision: 0.6962 - recall: 0.7397
Epoch 2/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5526 - acc: 0.7259 - precision: 0.7162 - recall: 0.7467
Epoch 3/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5393 - acc: 0.7321 - precision: 0.7240 - recall: 0.7488
Epoch 4/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5289 - acc: 0.7445 - precision: 0.7358 - recall: 0.7614
Epoch 5/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5212 - acc: 0.7486 - precision: 0.7432 - recall: 0.7581
Epoch 6/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5146 - acc: 0.7495 - precision: 0.7392 - recall: 0.7696
Epoch 7/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5095 - acc: 0.7543 - precision: 0.7454 - recall: 0.7710
Epoch 8/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5041 - acc: 0.7627 - precision: 0.7524 - recall: 0.7818
Epoch 9/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4917 - acc: 0.7704 - precision: 0.7615 - recall: 0.7860
Epoch 10/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4837 - acc: 0.7734 - precision: 0.7679 - recall: 0.7825
Epoch 11/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4716 - acc: 0.7786 - precision: 0.7662 - recall: 0.8007
Epoch 12/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4648 - acc: 0.7839 - precision: 0.7760 - recall: 0.7971
88/88 [==============================] - 1s 3ms/step - loss: 0.5559 - acc: 0.7325 - precision: 0.7144 - recall: 0.7779
Model: "sequential_91"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_273 (Conv2D) (None, 30, 30, 32) 320
max_pooling2d_273 (MaxPooli (None, 15, 15, 32) 0
ng2D)
conv2d_274 (Conv2D) (None, 13, 13, 64) 18496
max_pooling2d_274 (MaxPooli (None, 6, 6, 64) 0
ng2D)
conv2d_275 (Conv2D) (None, 4, 4, 128) 73856
max_pooling2d_275 (MaxPooli (None, 2, 2, 128) 0
ng2D)
flatten_91 (Flatten) (None, 512) 0
dense_182 (Dense) (None, 512) 262656
dropout_89 (Dropout) (None, 512) 0
dense_183 (Dense) (None, 1) 513
=================================================================
Total params: 355,841
Trainable params: 355,841
Non-trainable params: 0
_________________________________________________________________
Epoch 1/12
175/175 [==============================] - 3s 4ms/step - loss: 0.6128 - acc: 0.6614 - precision: 0.6803 - recall: 0.6938
Epoch 2/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5534 - acc: 0.7216 - precision: 0.7154 - recall: 0.7290
Epoch 3/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5416 - acc: 0.7323 - precision: 0.7242 - recall: 0.7438
Epoch 4/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5365 - acc: 0.7318 - precision: 0.7267 - recall: 0.7366
Epoch 5/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5234 - acc: 0.7430 - precision: 0.7379 - recall: 0.7478
Epoch 6/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5150 - acc: 0.7514 - precision: 0.7432 - recall: 0.7625
Epoch 7/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5102 - acc: 0.7529 - precision: 0.7480 - recall: 0.7571
Epoch 8/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5028 - acc: 0.7584 - precision: 0.7539 - recall: 0.7618
Epoch 9/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4875 - acc: 0.7638 - precision: 0.7611 - recall: 0.7636
Epoch 10/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4803 - acc: 0.7654 - precision: 0.7645 - recall: 0.7618
Epoch 11/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4636 - acc: 0.7775 - precision: 0.7774 - recall: 0.7729
Epoch 12/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4530 - acc: 0.7845 - precision: 0.7833 - recall: 0.7819
88/88 [==============================] - 1s 3ms/step - loss: 0.5573 - acc: 0.7400 - precision: 0.7148 - recall: 0.8114
Model: "sequential_92"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_276 (Conv2D) (None, 30, 30, 32) 320
max_pooling2d_276 (MaxPooli (None, 15, 15, 32) 0
ng2D)
conv2d_277 (Conv2D) (None, 13, 13, 64) 18496
max_pooling2d_277 (MaxPooli (None, 6, 6, 64) 0
ng2D)
conv2d_278 (Conv2D) (None, 4, 4, 128) 73856
max_pooling2d_278 (MaxPooli (None, 2, 2, 128) 0
ng2D)
flatten_92 (Flatten) (None, 512) 0
dense_184 (Dense) (None, 512) 262656
dropout_90 (Dropout) (None, 512) 0
dense_185 (Dense) (None, 1) 513
=================================================================
Total params: 355,841
Trainable params: 355,841
Non-trainable params: 0
_________________________________________________________________
Epoch 1/12
175/175 [==============================] - 3s 4ms/step - loss: 0.6007 - acc: 0.6761 - precision: 0.6914 - recall: 0.7250
Epoch 2/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5467 - acc: 0.7300 - precision: 0.7273 - recall: 0.7438
Epoch 3/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5362 - acc: 0.7412 - precision: 0.7375 - recall: 0.7565
Epoch 4/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5294 - acc: 0.7477 - precision: 0.7415 - recall: 0.7675
Epoch 5/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5232 - acc: 0.7511 - precision: 0.7491 - recall: 0.7619
Epoch 6/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5142 - acc: 0.7546 - precision: 0.7464 - recall: 0.7781
Epoch 7/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5093 - acc: 0.7521 - precision: 0.7464 - recall: 0.7707
Epoch 8/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5019 - acc: 0.7641 - precision: 0.7612 - recall: 0.7760
Epoch 9/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4973 - acc: 0.7675 - precision: 0.7606 - recall: 0.7870
Epoch 10/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4874 - acc: 0.7696 - precision: 0.7657 - recall: 0.7831
Epoch 11/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4733 - acc: 0.7816 - precision: 0.7759 - recall: 0.7976
Epoch 12/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4671 - acc: 0.7841 - precision: 0.7802 - recall: 0.7965
88/88 [==============================] - 1s 4ms/step - loss: 0.5445 - acc: 0.7418 - precision: 0.7006 - recall: 0.8275
Model: "sequential_93"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_279 (Conv2D) (None, 30, 30, 32) 320
max_pooling2d_279 (MaxPooli (None, 15, 15, 32) 0
ng2D)
conv2d_280 (Conv2D) (None, 13, 13, 64) 18496
max_pooling2d_280 (MaxPooli (None, 6, 6, 64) 0
ng2D)
conv2d_281 (Conv2D) (None, 4, 4, 128) 73856
max_pooling2d_281 (MaxPooli (None, 2, 2, 128) 0
ng2D)
flatten_93 (Flatten) (None, 512) 0
dense_186 (Dense) (None, 512) 262656
dropout_91 (Dropout) (None, 512) 0
dense_187 (Dense) (None, 1) 513
=================================================================
Total params: 355,841
Trainable params: 355,841
Non-trainable params: 0
_________________________________________________________________
Epoch 1/12
175/175 [==============================] - 3s 4ms/step - loss: 0.5980 - acc: 0.6873 - precision: 0.6866 - recall: 0.7479
Epoch 2/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5467 - acc: 0.7302 - precision: 0.7235 - recall: 0.7435
Epoch 3/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5380 - acc: 0.7345 - precision: 0.7285 - recall: 0.7460
Epoch 4/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5252 - acc: 0.7468 - precision: 0.7390 - recall: 0.7617
Epoch 5/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5153 - acc: 0.7548 - precision: 0.7486 - recall: 0.7660
Epoch 6/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5049 - acc: 0.7548 - precision: 0.7453 - recall: 0.7728
Epoch 7/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5015 - acc: 0.7580 - precision: 0.7503 - recall: 0.7721
Epoch 8/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4887 - acc: 0.7655 - precision: 0.7576 - recall: 0.7796
Epoch 9/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4791 - acc: 0.7746 - precision: 0.7659 - recall: 0.7900
Epoch 10/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4680 - acc: 0.7820 - precision: 0.7759 - recall: 0.7918
Epoch 11/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4567 - acc: 0.7857 - precision: 0.7770 - recall: 0.8004
Epoch 12/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4470 - acc: 0.7909 - precision: 0.7839 - recall: 0.8021
88/88 [==============================] - 1s 3ms/step - loss: 0.5564 - acc: 0.7296 - precision: 0.6971 - recall: 0.8157
Model: "sequential_94"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_282 (Conv2D) (None, 30, 30, 32) 320
max_pooling2d_282 (MaxPooli (None, 15, 15, 32) 0
ng2D)
conv2d_283 (Conv2D) (None, 13, 13, 64) 18496
max_pooling2d_283 (MaxPooli (None, 6, 6, 64) 0
ng2D)
conv2d_284 (Conv2D) (None, 4, 4, 128) 73856
max_pooling2d_284 (MaxPooli (None, 2, 2, 128) 0
ng2D)
flatten_94 (Flatten) (None, 512) 0
dense_188 (Dense) (None, 512) 262656
dropout_92 (Dropout) (None, 512) 0
dense_189 (Dense) (None, 1) 513
=================================================================
Total params: 355,841
Trainable params: 355,841
Non-trainable params: 0
_________________________________________________________________
Epoch 1/12
175/175 [==============================] - 3s 5ms/step - loss: 0.5824 - acc: 0.6936 - precision: 0.6925 - recall: 0.7357
Epoch 2/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5417 - acc: 0.7354 - precision: 0.7271 - recall: 0.7470
Epoch 3/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5281 - acc: 0.7423 - precision: 0.7367 - recall: 0.7481
Epoch 4/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5228 - acc: 0.7454 - precision: 0.7378 - recall: 0.7553
Epoch 5/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5076 - acc: 0.7521 - precision: 0.7471 - recall: 0.7567
Epoch 6/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4870 - acc: 0.7686 - precision: 0.7623 - recall: 0.7755
Epoch 7/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4791 - acc: 0.7789 - precision: 0.7718 - recall: 0.7873
Epoch 8/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4631 - acc: 0.7814 - precision: 0.7766 - recall: 0.7855
Epoch 9/12
175/175 [==============================] - 1s 6ms/step - loss: 0.4455 - acc: 0.8007 - precision: 0.7910 - recall: 0.8132
Epoch 10/12
175/175 [==============================] - 1s 6ms/step - loss: 0.4154 - acc: 0.8109 - precision: 0.8035 - recall: 0.8194
Epoch 11/12
175/175 [==============================] - 1s 5ms/step - loss: 0.3880 - acc: 0.8259 - precision: 0.8172 - recall: 0.8363
Epoch 12/12
175/175 [==============================] - 1s 5ms/step - loss: 0.3695 - acc: 0.8388 - precision: 0.8303 - recall: 0.8485
88/88 [==============================] - 1s 5ms/step - loss: 0.5828 - acc: 0.7407 - precision: 0.7154 - recall: 0.8121
Model: "sequential_95"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_285 (Conv2D) (None, 30, 30, 32) 320
max_pooling2d_285 (MaxPooli (None, 15, 15, 32) 0
ng2D)
conv2d_286 (Conv2D) (None, 13, 13, 64) 18496
max_pooling2d_286 (MaxPooli (None, 6, 6, 64) 0
ng2D)
conv2d_287 (Conv2D) (None, 4, 4, 128) 73856
max_pooling2d_287 (MaxPooli (None, 2, 2, 128) 0
ng2D)
flatten_95 (Flatten) (None, 512) 0
dense_190 (Dense) (None, 512) 262656
dropout_93 (Dropout) (None, 512) 0
dense_191 (Dense) (None, 1) 513
=================================================================
Total params: 355,841
Trainable params: 355,841
Non-trainable params: 0
_________________________________________________________________
Epoch 1/12
175/175 [==============================] - 3s 4ms/step - loss: 0.5822 - acc: 0.6948 - precision: 0.7019 - recall: 0.7417
Epoch 2/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5465 - acc: 0.7304 - precision: 0.7312 - recall: 0.7364
Epoch 3/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5337 - acc: 0.7445 - precision: 0.7401 - recall: 0.7608
Epoch 4/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5269 - acc: 0.7468 - precision: 0.7382 - recall: 0.7721
Epoch 5/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5133 - acc: 0.7564 - precision: 0.7512 - recall: 0.7735
Epoch 6/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5029 - acc: 0.7634 - precision: 0.7547 - recall: 0.7870
Epoch 7/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4922 - acc: 0.7705 - precision: 0.7627 - recall: 0.7916
Epoch 8/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4812 - acc: 0.7759 - precision: 0.7689 - recall: 0.7948
Epoch 9/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4684 - acc: 0.7818 - precision: 0.7767 - recall: 0.7965
Epoch 10/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4500 - acc: 0.7854 - precision: 0.7775 - recall: 0.8050
Epoch 11/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4257 - acc: 0.8011 - precision: 0.7952 - recall: 0.8160
Epoch 12/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4037 - acc: 0.8123 - precision: 0.8102 - recall: 0.8202
88/88 [==============================] - 1s 3ms/step - loss: 0.5534 - acc: 0.7500 - precision: 0.7259 - recall: 0.7882
Model: "sequential_96"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_288 (Conv2D) (None, 30, 30, 32) 320
max_pooling2d_288 (MaxPooli (None, 15, 15, 32) 0
ng2D)
conv2d_289 (Conv2D) (None, 13, 13, 64) 18496
max_pooling2d_289 (MaxPooli (None, 6, 6, 64) 0
ng2D)
conv2d_290 (Conv2D) (None, 4, 4, 128) 73856
max_pooling2d_290 (MaxPooli (None, 2, 2, 128) 0
ng2D)
flatten_96 (Flatten) (None, 512) 0
dense_192 (Dense) (None, 512) 262656
dropout_94 (Dropout) (None, 512) 0
dense_193 (Dense) (None, 1) 513
=================================================================
Total params: 355,841
Trainable params: 355,841
Non-trainable params: 0
_________________________________________________________________
Epoch 1/12
175/175 [==============================] - 3s 4ms/step - loss: 0.5858 - acc: 0.6932 - precision: 0.7013 - recall: 0.7316
Epoch 2/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5461 - acc: 0.7257 - precision: 0.7174 - recall: 0.7431
Epoch 3/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5332 - acc: 0.7389 - precision: 0.7321 - recall: 0.7521
Epoch 4/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5191 - acc: 0.7518 - precision: 0.7410 - recall: 0.7728
Epoch 5/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5046 - acc: 0.7557 - precision: 0.7499 - recall: 0.7660
Epoch 6/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4900 - acc: 0.7595 - precision: 0.7502 - recall: 0.7767
Epoch 7/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4773 - acc: 0.7757 - precision: 0.7653 - recall: 0.7943
Epoch 8/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4643 - acc: 0.7793 - precision: 0.7702 - recall: 0.7950
Epoch 9/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4417 - acc: 0.7966 - precision: 0.7830 - recall: 0.8197
Epoch 10/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4175 - acc: 0.8086 - precision: 0.7990 - recall: 0.8236
Epoch 11/12
175/175 [==============================] - 1s 4ms/step - loss: 0.3992 - acc: 0.8118 - precision: 0.7956 - recall: 0.8383
Epoch 12/12
175/175 [==============================] - 1s 4ms/step - loss: 0.3702 - acc: 0.8296 - precision: 0.8193 - recall: 0.8451
88/88 [==============================] - 1s 3ms/step - loss: 0.5715 - acc: 0.7386 - precision: 0.7215 - recall: 0.7801
Model: "sequential_97"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_291 (Conv2D) (None, 30, 30, 32) 320
max_pooling2d_291 (MaxPooli (None, 15, 15, 32) 0
ng2D)
conv2d_292 (Conv2D) (None, 13, 13, 64) 18496
max_pooling2d_292 (MaxPooli (None, 6, 6, 64) 0
ng2D)
conv2d_293 (Conv2D) (None, 4, 4, 128) 73856
max_pooling2d_293 (MaxPooli (None, 2, 2, 128) 0
ng2D)
flatten_97 (Flatten) (None, 512) 0
dense_194 (Dense) (None, 512) 262656
dropout_95 (Dropout) (None, 512) 0
dense_195 (Dense) (None, 1) 513
=================================================================
Total params: 355,841
Trainable params: 355,841
Non-trainable params: 0
_________________________________________________________________
Epoch 1/12
175/175 [==============================] - 3s 5ms/step - loss: 0.5890 - acc: 0.6814 - precision: 0.6950 - recall: 0.7106
Epoch 2/12
175/175 [==============================] - 1s 6ms/step - loss: 0.5424 - acc: 0.7304 - precision: 0.7230 - recall: 0.7402
Epoch 3/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5327 - acc: 0.7384 - precision: 0.7330 - recall: 0.7438
Epoch 4/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5230 - acc: 0.7484 - precision: 0.7385 - recall: 0.7632
Epoch 5/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5075 - acc: 0.7502 - precision: 0.7438 - recall: 0.7575
Epoch 6/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4921 - acc: 0.7671 - precision: 0.7598 - recall: 0.7762
Epoch 7/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4818 - acc: 0.7779 - precision: 0.7709 - recall: 0.7859
Epoch 8/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4690 - acc: 0.7793 - precision: 0.7733 - recall: 0.7855
Epoch 9/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4415 - acc: 0.7946 - precision: 0.7877 - recall: 0.8024
Epoch 10/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4140 - acc: 0.8161 - precision: 0.8087 - recall: 0.8244
Epoch 11/12
175/175 [==============================] - 1s 4ms/step - loss: 0.3829 - acc: 0.8311 - precision: 0.8251 - recall: 0.8370
Epoch 12/12
175/175 [==============================] - 1s 4ms/step - loss: 0.3587 - acc: 0.8371 - precision: 0.8321 - recall: 0.8417
88/88 [==============================] - 1s 3ms/step - loss: 0.5813 - acc: 0.7404 - precision: 0.7230 - recall: 0.7917
Model: "sequential_98"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_294 (Conv2D) (None, 30, 30, 32) 320
max_pooling2d_294 (MaxPooli (None, 15, 15, 32) 0
ng2D)
conv2d_295 (Conv2D) (None, 13, 13, 64) 18496
max_pooling2d_295 (MaxPooli (None, 6, 6, 64) 0
ng2D)
conv2d_296 (Conv2D) (None, 4, 4, 128) 73856
max_pooling2d_296 (MaxPooli (None, 2, 2, 128) 0
ng2D)
flatten_98 (Flatten) (None, 512) 0
dense_196 (Dense) (None, 512) 262656
dropout_96 (Dropout) (None, 512) 0
dense_197 (Dense) (None, 1) 513
=================================================================
Total params: 355,841
Trainable params: 355,841
Non-trainable params: 0
_________________________________________________________________
Epoch 1/12
175/175 [==============================] - 3s 5ms/step - loss: 0.5821 - acc: 0.6934 - precision: 0.7026 - recall: 0.7360
Epoch 2/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5497 - acc: 0.7257 - precision: 0.7255 - recall: 0.7343
Epoch 3/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5355 - acc: 0.7434 - precision: 0.7407 - recall: 0.7562
Epoch 4/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5298 - acc: 0.7475 - precision: 0.7388 - recall: 0.7728
Epoch 5/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5184 - acc: 0.7527 - precision: 0.7462 - recall: 0.7728
Epoch 6/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5052 - acc: 0.7614 - precision: 0.7560 - recall: 0.7785
Epoch 7/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4979 - acc: 0.7664 - precision: 0.7587 - recall: 0.7877
Epoch 8/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4854 - acc: 0.7759 - precision: 0.7700 - recall: 0.7926
Epoch 9/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4715 - acc: 0.7830 - precision: 0.7767 - recall: 0.8001
Epoch 10/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4618 - acc: 0.7841 - precision: 0.7749 - recall: 0.8064
Epoch 11/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4354 - acc: 0.8016 - precision: 0.7930 - recall: 0.8213
Epoch 12/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4161 - acc: 0.8130 - precision: 0.8073 - recall: 0.8270
88/88 [==============================] - 1s 5ms/step - loss: 0.5338 - acc: 0.7496 - precision: 0.7375 - recall: 0.7606
Model: "sequential_99"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_297 (Conv2D) (None, 30, 30, 32) 320
max_pooling2d_297 (MaxPooli (None, 15, 15, 32) 0
ng2D)
conv2d_298 (Conv2D) (None, 13, 13, 64) 18496
max_pooling2d_298 (MaxPooli (None, 6, 6, 64) 0
ng2D)
conv2d_299 (Conv2D) (None, 4, 4, 128) 73856
max_pooling2d_299 (MaxPooli (None, 2, 2, 128) 0
ng2D)
flatten_99 (Flatten) (None, 512) 0
dense_198 (Dense) (None, 512) 262656
dropout_97 (Dropout) (None, 512) 0
dense_199 (Dense) (None, 1) 513
=================================================================
Total params: 355,841
Trainable params: 355,841
Non-trainable params: 0
_________________________________________________________________
Epoch 1/12
175/175 [==============================] - 3s 5ms/step - loss: 0.5847 - acc: 0.6936 - precision: 0.7035 - recall: 0.7263
Epoch 2/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5508 - acc: 0.7257 - precision: 0.7196 - recall: 0.7381
Epoch 3/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5364 - acc: 0.7366 - precision: 0.7344 - recall: 0.7399
Epoch 4/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5190 - acc: 0.7468 - precision: 0.7373 - recall: 0.7653
Epoch 5/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5071 - acc: 0.7563 - precision: 0.7479 - recall: 0.7717
Epoch 6/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4915 - acc: 0.7627 - precision: 0.7547 - recall: 0.7771
Epoch 7/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4804 - acc: 0.7713 - precision: 0.7627 - recall: 0.7864
Epoch 8/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4697 - acc: 0.7807 - precision: 0.7721 - recall: 0.7953
Epoch 9/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4554 - acc: 0.7905 - precision: 0.7768 - recall: 0.8143
Epoch 10/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4351 - acc: 0.7971 - precision: 0.7899 - recall: 0.8086
Epoch 11/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4169 - acc: 0.8096 - precision: 0.7997 - recall: 0.8254
Epoch 12/12
175/175 [==============================] - 1s 5ms/step - loss: 0.3912 - acc: 0.8227 - precision: 0.8128 - recall: 0.8376
88/88 [==============================] - 1s 3ms/step - loss: 0.5547 - acc: 0.7407 - precision: 0.7235 - recall: 0.7822
Model: "sequential_100"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_300 (Conv2D) (None, 30, 30, 32) 320
max_pooling2d_300 (MaxPooli (None, 15, 15, 32) 0
ng2D)
conv2d_301 (Conv2D) (None, 13, 13, 64) 18496
max_pooling2d_301 (MaxPooli (None, 6, 6, 64) 0
ng2D)
conv2d_302 (Conv2D) (None, 4, 4, 128) 73856
max_pooling2d_302 (MaxPooli (None, 2, 2, 128) 0
ng2D)
flatten_100 (Flatten) (None, 512) 0
dense_200 (Dense) (None, 512) 262656
dropout_98 (Dropout) (None, 512) 0
dense_201 (Dense) (None, 1) 513
=================================================================
Total params: 355,841
Trainable params: 355,841
Non-trainable params: 0
_________________________________________________________________
Epoch 1/12
175/175 [==============================] - 3s 4ms/step - loss: 0.5909 - acc: 0.6789 - precision: 0.6925 - recall: 0.7137
Epoch 2/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5472 - acc: 0.7321 - precision: 0.7267 - recall: 0.7377
Epoch 3/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5347 - acc: 0.7395 - precision: 0.7326 - recall: 0.7481
Epoch 4/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5286 - acc: 0.7425 - precision: 0.7342 - recall: 0.7542
Epoch 5/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5143 - acc: 0.7486 - precision: 0.7425 - recall: 0.7553
Epoch 6/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5024 - acc: 0.7566 - precision: 0.7488 - recall: 0.7668
Epoch 7/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4942 - acc: 0.7636 - precision: 0.7559 - recall: 0.7733
Epoch 8/12
175/175 [==============================] - 1s 6ms/step - loss: 0.4833 - acc: 0.7686 - precision: 0.7590 - recall: 0.7819
Epoch 9/12
175/175 [==============================] - 1s 6ms/step - loss: 0.4626 - acc: 0.7843 - precision: 0.7761 - recall: 0.7945
Epoch 10/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4504 - acc: 0.7857 - precision: 0.7803 - recall: 0.7909
Epoch 11/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4152 - acc: 0.8100 - precision: 0.8061 - recall: 0.8125
Epoch 12/12
175/175 [==============================] - 1s 5ms/step - loss: 0.3998 - acc: 0.8159 - precision: 0.8091 - recall: 0.8233
88/88 [==============================] - 1s 3ms/step - loss: 0.5374 - acc: 0.7514 - precision: 0.7325 - recall: 0.8037
Model: "sequential_101"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_303 (Conv2D) (None, 30, 30, 32) 320
max_pooling2d_303 (MaxPooli (None, 15, 15, 32) 0
ng2D)
conv2d_304 (Conv2D) (None, 13, 13, 64) 18496
max_pooling2d_304 (MaxPooli (None, 6, 6, 64) 0
ng2D)
conv2d_305 (Conv2D) (None, 4, 4, 128) 73856
max_pooling2d_305 (MaxPooli (None, 2, 2, 128) 0
ng2D)
flatten_101 (Flatten) (None, 512) 0
dense_202 (Dense) (None, 512) 262656
dropout_99 (Dropout) (None, 512) 0
dense_203 (Dense) (None, 1) 513
=================================================================
Total params: 355,841
Trainable params: 355,841
Non-trainable params: 0
_________________________________________________________________
Epoch 1/12
175/175 [==============================] - 3s 5ms/step - loss: 0.5857 - acc: 0.6948 - precision: 0.7082 - recall: 0.7377
Epoch 2/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5490 - acc: 0.7225 - precision: 0.7254 - recall: 0.7243
Epoch 3/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5360 - acc: 0.7418 - precision: 0.7396 - recall: 0.7537
Epoch 4/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5276 - acc: 0.7459 - precision: 0.7380 - recall: 0.7696
Epoch 5/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5186 - acc: 0.7470 - precision: 0.7445 - recall: 0.7590
Epoch 6/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5061 - acc: 0.7607 - precision: 0.7545 - recall: 0.7795
Epoch 7/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4967 - acc: 0.7645 - precision: 0.7581 - recall: 0.7831
Epoch 8/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4857 - acc: 0.7730 - precision: 0.7686 - recall: 0.7873
Epoch 9/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4742 - acc: 0.7807 - precision: 0.7753 - recall: 0.7962
Epoch 10/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4596 - acc: 0.7882 - precision: 0.7787 - recall: 0.8107
Epoch 11/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4344 - acc: 0.7952 - precision: 0.7872 - recall: 0.8142
Epoch 12/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4163 - acc: 0.8050 - precision: 0.7990 - recall: 0.8199
88/88 [==============================] - 1s 3ms/step - loss: 0.5367 - acc: 0.7450 - precision: 0.7191 - recall: 0.7882
Model: "sequential_102"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_306 (Conv2D) (None, 30, 30, 32) 320
max_pooling2d_306 (MaxPooli (None, 15, 15, 32) 0
ng2D)
conv2d_307 (Conv2D) (None, 13, 13, 64) 18496
max_pooling2d_307 (MaxPooli (None, 6, 6, 64) 0
ng2D)
conv2d_308 (Conv2D) (None, 4, 4, 128) 73856
max_pooling2d_308 (MaxPooli (None, 2, 2, 128) 0
ng2D)
flatten_102 (Flatten) (None, 512) 0
dense_204 (Dense) (None, 512) 262656
dropout_100 (Dropout) (None, 512) 0
dense_205 (Dense) (None, 1) 513
=================================================================
Total params: 355,841
Trainable params: 355,841
Non-trainable params: 0
_________________________________________________________________
Epoch 1/12
175/175 [==============================] - 3s 4ms/step - loss: 0.5855 - acc: 0.6945 - precision: 0.6985 - recall: 0.7359
Epoch 2/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5467 - acc: 0.7295 - precision: 0.7235 - recall: 0.7413
Epoch 3/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5346 - acc: 0.7373 - precision: 0.7310 - recall: 0.7496
Epoch 4/12
175/175 [==============================] - 1s 6ms/step - loss: 0.5176 - acc: 0.7495 - precision: 0.7412 - recall: 0.7653
Epoch 5/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5068 - acc: 0.7589 - precision: 0.7511 - recall: 0.7732
Epoch 6/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4928 - acc: 0.7634 - precision: 0.7526 - recall: 0.7835
Epoch 7/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4819 - acc: 0.7743 - precision: 0.7622 - recall: 0.7961
Epoch 8/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4647 - acc: 0.7832 - precision: 0.7755 - recall: 0.7961
Epoch 9/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4488 - acc: 0.7911 - precision: 0.7805 - recall: 0.8089
Epoch 10/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4216 - acc: 0.8075 - precision: 0.7990 - recall: 0.8208
Epoch 11/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4046 - acc: 0.8105 - precision: 0.7986 - recall: 0.8297
Epoch 12/12
175/175 [==============================] - 1s 4ms/step - loss: 0.3734 - acc: 0.8302 - precision: 0.8222 - recall: 0.8419
88/88 [==============================] - 1s 3ms/step - loss: 0.5961 - acc: 0.7318 - precision: 0.7070 - recall: 0.7950
Model: "sequential_103"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_309 (Conv2D) (None, 30, 30, 32) 320
max_pooling2d_309 (MaxPooli (None, 15, 15, 32) 0
ng2D)
conv2d_310 (Conv2D) (None, 13, 13, 64) 18496
max_pooling2d_310 (MaxPooli (None, 6, 6, 64) 0
ng2D)
conv2d_311 (Conv2D) (None, 4, 4, 128) 73856
max_pooling2d_311 (MaxPooli (None, 2, 2, 128) 0
ng2D)
flatten_103 (Flatten) (None, 512) 0
dense_206 (Dense) (None, 512) 262656
dropout_101 (Dropout) (None, 512) 0
dense_207 (Dense) (None, 1) 513
=================================================================
Total params: 355,841
Trainable params: 355,841
Non-trainable params: 0
_________________________________________________________________
Epoch 1/12
175/175 [==============================] - 3s 5ms/step - loss: 0.5945 - acc: 0.6825 - precision: 0.6886 - recall: 0.7220
Epoch 2/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5484 - acc: 0.7287 - precision: 0.7245 - recall: 0.7316
Epoch 3/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5345 - acc: 0.7402 - precision: 0.7334 - recall: 0.7485
Epoch 4/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5282 - acc: 0.7412 - precision: 0.7306 - recall: 0.7582
Epoch 5/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5134 - acc: 0.7521 - precision: 0.7453 - recall: 0.7603
Epoch 6/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5005 - acc: 0.7607 - precision: 0.7524 - recall: 0.7719
Epoch 7/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4914 - acc: 0.7677 - precision: 0.7604 - recall: 0.7765
Epoch 8/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4767 - acc: 0.7711 - precision: 0.7624 - recall: 0.7827
Epoch 9/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4628 - acc: 0.7830 - precision: 0.7755 - recall: 0.7920
Epoch 10/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4408 - acc: 0.8000 - precision: 0.7920 - recall: 0.8096
Epoch 11/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4092 - acc: 0.8082 - precision: 0.8022 - recall: 0.8143
Epoch 12/12
175/175 [==============================] - 1s 4ms/step - loss: 0.3937 - acc: 0.8184 - precision: 0.8126 - recall: 0.8240
88/88 [==============================] - 1s 3ms/step - loss: 0.5422 - acc: 0.7554 - precision: 0.7390 - recall: 0.8008
Model: "sequential_104"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_312 (Conv2D) (None, 30, 30, 32) 320
max_pooling2d_312 (MaxPooli (None, 15, 15, 32) 0
ng2D)
conv2d_313 (Conv2D) (None, 13, 13, 64) 18496
max_pooling2d_313 (MaxPooli (None, 6, 6, 64) 0
ng2D)
conv2d_314 (Conv2D) (None, 4, 4, 128) 73856
max_pooling2d_314 (MaxPooli (None, 2, 2, 128) 0
ng2D)
flatten_104 (Flatten) (None, 512) 0
dense_208 (Dense) (None, 512) 262656
dropout_102 (Dropout) (None, 512) 0
dense_209 (Dense) (None, 1) 513
=================================================================
Total params: 355,841
Trainable params: 355,841
Non-trainable params: 0
_________________________________________________________________
Epoch 1/12
175/175 [==============================] - 3s 5ms/step - loss: 0.5771 - acc: 0.6986 - precision: 0.7138 - recall: 0.7365
Epoch 2/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5479 - acc: 0.7318 - precision: 0.7313 - recall: 0.7406
Epoch 3/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5354 - acc: 0.7423 - precision: 0.7395 - recall: 0.7555
Epoch 4/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5243 - acc: 0.7475 - precision: 0.7396 - recall: 0.7711
Epoch 5/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5144 - acc: 0.7529 - precision: 0.7488 - recall: 0.7679
Epoch 6/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5001 - acc: 0.7643 - precision: 0.7563 - recall: 0.7863
Epoch 7/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4899 - acc: 0.7693 - precision: 0.7625 - recall: 0.7884
Epoch 8/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4796 - acc: 0.7750 - precision: 0.7689 - recall: 0.7923
Epoch 9/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4617 - acc: 0.7904 - precision: 0.7850 - recall: 0.8050
Epoch 10/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4396 - acc: 0.7945 - precision: 0.7873 - recall: 0.8121
Epoch 11/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4235 - acc: 0.8071 - precision: 0.7990 - recall: 0.8255
Epoch 12/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4027 - acc: 0.8184 - precision: 0.8170 - recall: 0.8248
88/88 [==============================] - 1s 3ms/step - loss: 0.5416 - acc: 0.7514 - precision: 0.7348 - recall: 0.7722
Model: "sequential_105"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_315 (Conv2D) (None, 30, 30, 32) 320
max_pooling2d_315 (MaxPooli (None, 15, 15, 32) 0
ng2D)
conv2d_316 (Conv2D) (None, 13, 13, 64) 18496
max_pooling2d_316 (MaxPooli (None, 6, 6, 64) 0
ng2D)
conv2d_317 (Conv2D) (None, 4, 4, 128) 73856
max_pooling2d_317 (MaxPooli (None, 2, 2, 128) 0
ng2D)
flatten_105 (Flatten) (None, 512) 0
dense_210 (Dense) (None, 512) 262656
dropout_103 (Dropout) (None, 512) 0
dense_211 (Dense) (None, 1) 513
=================================================================
Total params: 355,841
Trainable params: 355,841
Non-trainable params: 0
_________________________________________________________________
Epoch 1/12
175/175 [==============================] - 3s 5ms/step - loss: 0.5861 - acc: 0.6905 - precision: 0.6994 - recall: 0.7321
Epoch 2/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5490 - acc: 0.7271 - precision: 0.7207 - recall: 0.7403
Epoch 3/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5395 - acc: 0.7377 - precision: 0.7330 - recall: 0.7463
Epoch 4/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5246 - acc: 0.7455 - precision: 0.7378 - recall: 0.7603
Epoch 5/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5114 - acc: 0.7595 - precision: 0.7510 - recall: 0.7750
Epoch 6/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5010 - acc: 0.7552 - precision: 0.7438 - recall: 0.7771
Epoch 7/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4874 - acc: 0.7641 - precision: 0.7547 - recall: 0.7814
Epoch 8/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4774 - acc: 0.7739 - precision: 0.7628 - recall: 0.7939
Epoch 9/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4620 - acc: 0.7821 - precision: 0.7728 - recall: 0.7982
Epoch 10/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4424 - acc: 0.7946 - precision: 0.7839 - recall: 0.8125
Epoch 11/12
175/175 [==============================] - 1s 6ms/step - loss: 0.4212 - acc: 0.8050 - precision: 0.7915 - recall: 0.8272
Epoch 12/12
175/175 [==============================] - 1s 6ms/step - loss: 0.4033 - acc: 0.8141 - precision: 0.8043 - recall: 0.8293
88/88 [==============================] - 1s 3ms/step - loss: 0.5558 - acc: 0.7379 - precision: 0.7067 - recall: 0.8164
Model: "sequential_106"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_318 (Conv2D) (None, 30, 30, 32) 320
max_pooling2d_318 (MaxPooli (None, 15, 15, 32) 0
ng2D)
conv2d_319 (Conv2D) (None, 13, 13, 64) 18496
max_pooling2d_319 (MaxPooli (None, 6, 6, 64) 0
ng2D)
conv2d_320 (Conv2D) (None, 4, 4, 128) 73856
max_pooling2d_320 (MaxPooli (None, 2, 2, 128) 0
ng2D)
flatten_106 (Flatten) (None, 512) 0
dense_212 (Dense) (None, 512) 262656
dropout_104 (Dropout) (None, 512) 0
dense_213 (Dense) (None, 1) 513
=================================================================
Total params: 355,841
Trainable params: 355,841
Non-trainable params: 0
_________________________________________________________________
Epoch 1/12
175/175 [==============================] - 3s 5ms/step - loss: 0.5912 - acc: 0.6802 - precision: 0.6895 - recall: 0.7213
Epoch 2/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5433 - acc: 0.7337 - precision: 0.7285 - recall: 0.7388
Epoch 3/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5349 - acc: 0.7361 - precision: 0.7290 - recall: 0.7452
Epoch 4/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5291 - acc: 0.7396 - precision: 0.7305 - recall: 0.7531
Epoch 5/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5114 - acc: 0.7545 - precision: 0.7486 - recall: 0.7607
Epoch 6/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4990 - acc: 0.7616 - precision: 0.7510 - recall: 0.7773
Epoch 7/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4918 - acc: 0.7688 - precision: 0.7613 - recall: 0.7780
Epoch 8/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4770 - acc: 0.7693 - precision: 0.7608 - recall: 0.7805
Epoch 9/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4567 - acc: 0.7880 - precision: 0.7797 - recall: 0.7985
Epoch 10/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4405 - acc: 0.7973 - precision: 0.7900 - recall: 0.8057
Epoch 11/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4114 - acc: 0.8095 - precision: 0.8029 - recall: 0.8165
Epoch 12/12
175/175 [==============================] - 1s 4ms/step - loss: 0.3912 - acc: 0.8243 - precision: 0.8166 - recall: 0.8330
88/88 [==============================] - 1s 3ms/step - loss: 0.5493 - acc: 0.7514 - precision: 0.7526 - recall: 0.7600
Model: "sequential_107"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_321 (Conv2D) (None, 30, 30, 32) 320
max_pooling2d_321 (MaxPooli (None, 15, 15, 32) 0
ng2D)
conv2d_322 (Conv2D) (None, 13, 13, 64) 18496
max_pooling2d_322 (MaxPooli (None, 6, 6, 64) 0
ng2D)
conv2d_323 (Conv2D) (None, 4, 4, 128) 73856
max_pooling2d_323 (MaxPooli (None, 2, 2, 128) 0
ng2D)
flatten_107 (Flatten) (None, 512) 0
dense_214 (Dense) (None, 512) 262656
dropout_105 (Dropout) (None, 512) 0
dense_215 (Dense) (None, 1) 513
=================================================================
Total params: 355,841
Trainable params: 355,841
Non-trainable params: 0
_________________________________________________________________
Epoch 1/12
175/175 [==============================] - 4s 4ms/step - loss: 0.5835 - acc: 0.6989 - precision: 0.7162 - recall: 0.7273
Epoch 2/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5477 - acc: 0.7280 - precision: 0.7311 - recall: 0.7293
Epoch 3/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5353 - acc: 0.7411 - precision: 0.7358 - recall: 0.7597
Epoch 4/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5292 - acc: 0.7455 - precision: 0.7393 - recall: 0.7657
Epoch 5/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5161 - acc: 0.7484 - precision: 0.7446 - recall: 0.7633
Epoch 6/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5054 - acc: 0.7625 - precision: 0.7565 - recall: 0.7806
Epoch 7/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4948 - acc: 0.7691 - precision: 0.7624 - recall: 0.7880
Epoch 8/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4841 - acc: 0.7771 - precision: 0.7704 - recall: 0.7955
Epoch 9/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4761 - acc: 0.7823 - precision: 0.7779 - recall: 0.7958
Epoch 10/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4576 - acc: 0.7871 - precision: 0.7804 - recall: 0.8047
Epoch 11/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4371 - acc: 0.7993 - precision: 0.7900 - recall: 0.8202
Epoch 12/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4198 - acc: 0.8070 - precision: 0.8020 - recall: 0.8199
88/88 [==============================] - 1s 4ms/step - loss: 0.5361 - acc: 0.7504 - precision: 0.7320 - recall: 0.7751
Model: "sequential_108"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_324 (Conv2D) (None, 30, 30, 32) 320
max_pooling2d_324 (MaxPooli (None, 15, 15, 32) 0
ng2D)
conv2d_325 (Conv2D) (None, 13, 13, 64) 18496
max_pooling2d_325 (MaxPooli (None, 6, 6, 64) 0
ng2D)
conv2d_326 (Conv2D) (None, 4, 4, 128) 73856
max_pooling2d_326 (MaxPooli (None, 2, 2, 128) 0
ng2D)
flatten_108 (Flatten) (None, 512) 0
dense_216 (Dense) (None, 512) 262656
dropout_106 (Dropout) (None, 512) 0
dense_217 (Dense) (None, 1) 513
=================================================================
Total params: 355,841
Trainable params: 355,841
Non-trainable params: 0
_________________________________________________________________
Epoch 1/12
175/175 [==============================] - 3s 5ms/step - loss: 0.5878 - acc: 0.6880 - precision: 0.6984 - recall: 0.7275
Epoch 2/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5495 - acc: 0.7232 - precision: 0.7141 - recall: 0.7428
Epoch 3/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5389 - acc: 0.7350 - precision: 0.7290 - recall: 0.7467
Epoch 4/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5242 - acc: 0.7450 - precision: 0.7348 - recall: 0.7653
Epoch 5/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5101 - acc: 0.7625 - precision: 0.7541 - recall: 0.7778
Epoch 6/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4964 - acc: 0.7607 - precision: 0.7491 - recall: 0.7828
Epoch 7/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4839 - acc: 0.7739 - precision: 0.7670 - recall: 0.7857
Epoch 8/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4734 - acc: 0.7770 - precision: 0.7684 - recall: 0.7918
Epoch 9/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4552 - acc: 0.7891 - precision: 0.7789 - recall: 0.8064
Epoch 10/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4393 - acc: 0.7973 - precision: 0.7846 - recall: 0.8186
Epoch 11/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4208 - acc: 0.8027 - precision: 0.7928 - recall: 0.8186
Epoch 12/12
175/175 [==============================] - 1s 5ms/step - loss: 0.3915 - acc: 0.8152 - precision: 0.8060 - recall: 0.8293
88/88 [==============================] - 1s 3ms/step - loss: 0.5667 - acc: 0.7368 - precision: 0.7090 - recall: 0.8064
Model: "sequential_109"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_327 (Conv2D) (None, 30, 30, 32) 320
max_pooling2d_327 (MaxPooli (None, 15, 15, 32) 0
ng2D)
conv2d_328 (Conv2D) (None, 13, 13, 64) 18496
max_pooling2d_328 (MaxPooli (None, 6, 6, 64) 0
ng2D)
conv2d_329 (Conv2D) (None, 4, 4, 128) 73856
max_pooling2d_329 (MaxPooli (None, 2, 2, 128) 0
ng2D)
flatten_109 (Flatten) (None, 512) 0
dense_218 (Dense) (None, 512) 262656
dropout_107 (Dropout) (None, 512) 0
dense_219 (Dense) (None, 1) 513
=================================================================
Total params: 355,841
Trainable params: 355,841
Non-trainable params: 0
_________________________________________________________________
Epoch 1/12
175/175 [==============================] - 3s 7ms/step - loss: 0.5916 - acc: 0.6837 - precision: 0.6915 - recall: 0.7232
Epoch 2/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5451 - acc: 0.7300 - precision: 0.7220 - recall: 0.7413
Epoch 3/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5368 - acc: 0.7382 - precision: 0.7296 - recall: 0.7506
Epoch 4/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5280 - acc: 0.7396 - precision: 0.7297 - recall: 0.7549
Epoch 5/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5135 - acc: 0.7491 - precision: 0.7387 - recall: 0.7650
Epoch 6/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5027 - acc: 0.7584 - precision: 0.7493 - recall: 0.7711
Epoch 7/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4922 - acc: 0.7671 - precision: 0.7600 - recall: 0.7758
Epoch 8/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4812 - acc: 0.7704 - precision: 0.7600 - recall: 0.7852
Epoch 9/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4654 - acc: 0.7854 - precision: 0.7739 - recall: 0.8017
Epoch 10/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4448 - acc: 0.7920 - precision: 0.7820 - recall: 0.8053
Epoch 11/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4147 - acc: 0.8107 - precision: 0.8017 - recall: 0.8219
Epoch 12/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4021 - acc: 0.8161 - precision: 0.8098 - recall: 0.8226
88/88 [==============================] - 1s 3ms/step - loss: 0.5471 - acc: 0.7436 - precision: 0.7396 - recall: 0.7635
Model: "sequential_110"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_330 (Conv2D) (None, 30, 30, 32) 320
max_pooling2d_330 (MaxPooli (None, 15, 15, 32) 0
ng2D)
conv2d_331 (Conv2D) (None, 13, 13, 64) 18496
max_pooling2d_331 (MaxPooli (None, 6, 6, 64) 0
ng2D)
conv2d_332 (Conv2D) (None, 4, 4, 128) 73856
max_pooling2d_332 (MaxPooli (None, 2, 2, 128) 0
ng2D)
flatten_110 (Flatten) (None, 512) 0
dense_220 (Dense) (None, 512) 262656
dropout_108 (Dropout) (None, 512) 0
dense_221 (Dense) (None, 1) 513
=================================================================
Total params: 355,841
Trainable params: 355,841
Non-trainable params: 0
_________________________________________________________________
Epoch 1/12
175/175 [==============================] - 3s 5ms/step - loss: 0.5752 - acc: 0.7077 - precision: 0.7172 - recall: 0.7356
Epoch 2/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5456 - acc: 0.7312 - precision: 0.7312 - recall: 0.7392
Epoch 3/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5329 - acc: 0.7446 - precision: 0.7404 - recall: 0.7608
Epoch 4/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5242 - acc: 0.7504 - precision: 0.7435 - recall: 0.7714
Epoch 5/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5123 - acc: 0.7554 - precision: 0.7505 - recall: 0.7718
Epoch 6/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4966 - acc: 0.7675 - precision: 0.7595 - recall: 0.7891
Epoch 7/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4943 - acc: 0.7684 - precision: 0.7617 - recall: 0.7873
Epoch 8/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4812 - acc: 0.7743 - precision: 0.7675 - recall: 0.7930
Epoch 9/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4671 - acc: 0.7839 - precision: 0.7779 - recall: 0.8004
Epoch 10/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4500 - acc: 0.7880 - precision: 0.7788 - recall: 0.8100
Epoch 11/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4232 - acc: 0.8057 - precision: 0.7976 - recall: 0.8241
Epoch 12/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4089 - acc: 0.8130 - precision: 0.8029 - recall: 0.8344
88/88 [==============================] - 1s 4ms/step - loss: 0.5401 - acc: 0.7550 - precision: 0.7331 - recall: 0.7875
Model: "sequential_111"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_333 (Conv2D) (None, 30, 30, 32) 320
max_pooling2d_333 (MaxPooli (None, 15, 15, 32) 0
ng2D)
conv2d_334 (Conv2D) (None, 13, 13, 64) 18496
max_pooling2d_334 (MaxPooli (None, 6, 6, 64) 0
ng2D)
conv2d_335 (Conv2D) (None, 4, 4, 128) 73856
max_pooling2d_335 (MaxPooli (None, 2, 2, 128) 0
ng2D)
flatten_111 (Flatten) (None, 512) 0
dense_222 (Dense) (None, 512) 262656
dropout_109 (Dropout) (None, 512) 0
dense_223 (Dense) (None, 1) 513
=================================================================
Total params: 355,841
Trainable params: 355,841
Non-trainable params: 0
_________________________________________________________________
Epoch 1/12
175/175 [==============================] - 3s 5ms/step - loss: 0.5858 - acc: 0.6959 - precision: 0.7045 - recall: 0.7354
Epoch 2/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5497 - acc: 0.7254 - precision: 0.7189 - recall: 0.7385
Epoch 3/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5332 - acc: 0.7380 - precision: 0.7314 - recall: 0.7510
Epoch 4/12
175/175 [==============================] - 1s 5ms/step - loss: 0.5205 - acc: 0.7504 - precision: 0.7408 - recall: 0.7689
Epoch 5/12
175/175 [==============================] - 1s 4ms/step - loss: 0.5089 - acc: 0.7623 - precision: 0.7556 - recall: 0.7742
Epoch 6/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4997 - acc: 0.7580 - precision: 0.7505 - recall: 0.7717
Epoch 7/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4874 - acc: 0.7700 - precision: 0.7617 - recall: 0.7846
Epoch 8/12
175/175 [==============================] - 1s 5ms/step - loss: 0.4757 - acc: 0.7777 - precision: 0.7684 - recall: 0.7939
Epoch 9/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4591 - acc: 0.7800 - precision: 0.7707 - recall: 0.7961
Epoch 10/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4428 - acc: 0.7950 - precision: 0.7880 - recall: 0.8061
Epoch 11/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4297 - acc: 0.7995 - precision: 0.7883 - recall: 0.8179
Epoch 12/12
175/175 [==============================] - 1s 4ms/step - loss: 0.4050 - acc: 0.8125 - precision: 0.8020 - recall: 0.8290
88/88 [==============================] - 1s 3ms/step - loss: 0.5528 - acc: 0.7382 - precision: 0.7350 - recall: 0.7480
Model: "sequential_112"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_336 (Conv2D) (None, 30, 30, 32) 320
max_pooling2d_336 (MaxPooli (None, 15, 15, 32) 0
ng2D)
conv2d_337 (Conv2D) (None, 13, 13, 64) 18496
max_pooling2d_337 (MaxPooli (None, 6, 6, 64) 0
ng2D)
conv2d_338 (Conv2D) (None, 4, 4, 128) 73856
max_pooling2d_338 (MaxPooli (None, 2, 2, 128) 0
ng2D)
flatten_112 (Flatten) (None, 512) 0
dense_224 (Dense) (None, 512) 262656
dropout_110 (Dropout) (None, 512) 0
dense_225 (Dense) (None, 1) 513
=================================================================
Total params: 355,841
Trainable params: 355,841
Non-trainable params: 0
_________________________________________________________________
Epoch 1/12
263/263 [==============================] - 4s 6ms/step - loss: 0.5772 - acc: 0.6990 - precision: 0.7061 - recall: 0.7163
Epoch 2/12
263/263 [==============================] - 1s 5ms/step - loss: 0.5409 - acc: 0.7371 - precision: 0.7325 - recall: 0.7471
Epoch 3/12
263/263 [==============================] - 2s 6ms/step - loss: 0.5257 - acc: 0.7470 - precision: 0.7356 - recall: 0.7712
Epoch 4/12
263/263 [==============================] - 1s 5ms/step - loss: 0.5145 - acc: 0.7573 - precision: 0.7484 - recall: 0.7750
Epoch 5/12
263/263 [==============================] - 2s 7ms/step - loss: 0.5011 - acc: 0.7585 - precision: 0.7516 - recall: 0.7721
Epoch 6/12
263/263 [==============================] - 1s 5ms/step - loss: 0.4926 - acc: 0.7671 - precision: 0.7584 - recall: 0.7840
Epoch 7/12
263/263 [==============================] - 1s 5ms/step - loss: 0.4748 - acc: 0.7790 - precision: 0.7714 - recall: 0.7931
Epoch 8/12
263/263 [==============================] - 1s 5ms/step - loss: 0.4622 - acc: 0.7811 - precision: 0.7732 - recall: 0.7955
Epoch 9/12
263/263 [==============================] - 1s 5ms/step - loss: 0.4447 - acc: 0.7918 - precision: 0.7815 - recall: 0.8100
Epoch 10/12
263/263 [==============================] - 1s 5ms/step - loss: 0.4168 - acc: 0.8082 - precision: 0.7996 - recall: 0.8226
Epoch 11/12
263/263 [==============================] - 1s 5ms/step - loss: 0.3843 - acc: 0.8267 - precision: 0.8186 - recall: 0.8393
Epoch 12/12
263/263 [==============================] - 1s 5ms/step - loss: 0.3573 - acc: 0.8399 - precision: 0.8310 - recall: 0.8533
Best: 0.748214 using {'activation': 'LeakyReLU', 'learning_rate': 0.001, 'optimizer': 'sgd'}
0.745714 (0.005541) with: {'activation': 'relu', 'learning_rate': 0.0001, 'optimizer': 'adam'}
0.746548 (0.003515) with: {'activation': 'relu', 'learning_rate': 0.0001, 'optimizer': 'sgd'}
0.745476 (0.008146) with: {'activation': 'relu', 'learning_rate': 0.001, 'optimizer': 'adam'}
0.744524 (0.009869) with: {'activation': 'relu', 'learning_rate': 0.001, 'optimizer': 'sgd'}
0.741310 (0.006290) with: {'activation': 'relu', 'learning_rate': 0.01, 'optimizer': 'adam'}
0.737143 (0.005353) with: {'activation': 'relu', 'learning_rate': 0.01, 'optimizer': 'sgd'}
0.743095 (0.004960) with: {'activation': 'LeakyReLU', 'learning_rate': 0.0001, 'optimizer': 'adam'}
0.743571 (0.004296) with: {'activation': 'LeakyReLU', 'learning_rate': 0.0001, 'optimizer': 'sgd'}
0.742738 (0.008177) with: {'activation': 'LeakyReLU', 'learning_rate': 0.001, 'optimizer': 'adam'}
0.748214 (0.007497) with: {'activation': 'LeakyReLU', 'learning_rate': 0.001, 'optimizer': 'sgd'}
0.746190 (0.006665) with: {'activation': 'LeakyReLU', 'learning_rate': 0.01, 'optimizer': 'adam'}
0.745595 (0.007001) with: {'activation': 'LeakyReLU', 'learning_rate': 0.01, 'optimizer': 'sgd'}
The Best parameters returned after Grid Search: 0.748214 using {'activation': 'LeakyReLU', 'learning_rate': 0.001, 'optimizer': 'sgd'}
Lets build a model with these parameters and check its performance.
model_5 = create_model(optimizer='sgd', hidden_units=512, dropout_rate=0.5,
activation='LeakyReLU', learning_rate=0.001,
weight_init='he_normal')
history_5 = fit_model(model_5, NUM_OF_EPOCHS)
evaluate_model_perf(history_5, model_5, 'Model_Tuning_with_GridSearch')
Model: "sequential_114"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_342 (Conv2D) (None, 30, 30, 32) 320
max_pooling2d_342 (MaxPooli (None, 15, 15, 32) 0
ng2D)
conv2d_343 (Conv2D) (None, 13, 13, 64) 18496
max_pooling2d_343 (MaxPooli (None, 6, 6, 64) 0
ng2D)
conv2d_344 (Conv2D) (None, 4, 4, 128) 73856
max_pooling2d_344 (MaxPooli (None, 2, 2, 128) 0
ng2D)
flatten_114 (Flatten) (None, 512) 0
dense_228 (Dense) (None, 512) 262656
dropout_112 (Dropout) (None, 512) 0
dense_229 (Dense) (None, 1) 513
=================================================================
Total params: 355,841
Trainable params: 355,841
Non-trainable params: 0
_________________________________________________________________
Epoch 1/12
1049/1050 [============================>.] - ETA: 0s - loss: 0.6027 - acc: 0.6793 - precision: 0.7554 - recall: 0.7678
Epoch 1: val_acc did not improve from 0.74778
1050/1050 [==============================] - 18s 15ms/step - loss: 0.6025 - acc: 0.6794 - precision: 0.7554 - recall: 0.7679 - val_loss: 0.5732 - val_acc: 0.6967 - val_precision: 0.6791 - val_recall: 0.7456 - lr: 0.0010
Epoch 2/12
1048/1050 [============================>.] - ETA: 0s - loss: 0.5697 - acc: 0.7139 - precision: 0.7139 - recall: 0.7144
Epoch 2: val_acc did not improve from 0.74778
1050/1050 [==============================] - 15s 15ms/step - loss: 0.5701 - acc: 0.7136 - precision: 0.7132 - recall: 0.7145 - val_loss: 0.5647 - val_acc: 0.7139 - val_precision: 0.6811 - val_recall: 0.8044 - lr: 0.0010
Epoch 3/12
1050/1050 [==============================] - ETA: 0s - loss: 0.5615 - acc: 0.7205 - precision: 0.7158 - recall: 0.7314
Epoch 3: val_acc did not improve from 0.74778
1050/1050 [==============================] - 16s 15ms/step - loss: 0.5615 - acc: 0.7205 - precision: 0.7158 - recall: 0.7314 - val_loss: 0.5566 - val_acc: 0.7200 - val_precision: 0.6930 - val_recall: 0.7900 - lr: 0.0010
Epoch 4/12
1045/1050 [============================>.] - ETA: 0s - loss: 0.5566 - acc: 0.7217 - precision: 0.7188 - recall: 0.7282
Epoch 4: val_acc did not improve from 0.74778
1050/1050 [==============================] - 15s 14ms/step - loss: 0.5567 - acc: 0.7215 - precision: 0.7189 - recall: 0.7276 - val_loss: 0.5667 - val_acc: 0.7167 - val_precision: 0.7716 - val_recall: 0.6156 - lr: 0.0010
Epoch 5/12
1048/1050 [============================>.] - ETA: 0s - loss: 0.5582 - acc: 0.7244 - precision: 0.7212 - recall: 0.7314
Epoch 5: val_acc did not improve from 0.74778
1050/1050 [==============================] - 15s 15ms/step - loss: 0.5586 - acc: 0.7240 - precision: 0.7207 - recall: 0.7317 - val_loss: 0.5400 - val_acc: 0.7350 - val_precision: 0.7291 - val_recall: 0.7478 - lr: 0.0010
Epoch 6/12
1048/1050 [============================>.] - ETA: 0s - loss: 0.5530 - acc: 0.7241 - precision: 0.7247 - recall: 0.7232
Epoch 6: val_acc did not improve from 0.74778
1050/1050 [==============================] - 16s 15ms/step - loss: 0.5530 - acc: 0.7242 - precision: 0.7246 - recall: 0.7231 - val_loss: 0.5444 - val_acc: 0.7256 - val_precision: 0.7350 - val_recall: 0.7056 - lr: 0.0010
Epoch 7/12
1042/1050 [============================>.] - ETA: 0s - loss: 0.5482 - acc: 0.7241 - precision: 0.7236 - recall: 0.7247
Epoch 7: val_acc did not improve from 0.74778
1050/1050 [==============================] - 15s 14ms/step - loss: 0.5477 - acc: 0.7242 - precision: 0.7241 - recall: 0.7243 - val_loss: 0.5274 - val_acc: 0.7344 - val_precision: 0.7212 - val_recall: 0.7644 - lr: 0.0010
Epoch 8/12
1045/1050 [============================>.] - ETA: 0s - loss: 0.5435 - acc: 0.7300 - precision: 0.7284 - recall: 0.7345
Epoch 8: val_acc did not improve from 0.74778
1050/1050 [==============================] - 16s 15ms/step - loss: 0.5440 - acc: 0.7296 - precision: 0.7279 - recall: 0.7336 - val_loss: 0.5821 - val_acc: 0.6939 - val_precision: 0.8099 - val_recall: 0.5067 - lr: 0.0010
Epoch 9/12
1048/1050 [============================>.] - ETA: 0s - loss: 0.5457 - acc: 0.7307 - precision: 0.7305 - recall: 0.7312
Epoch 9: val_acc did not improve from 0.74778
1050/1050 [==============================] - 15s 15ms/step - loss: 0.5457 - acc: 0.7305 - precision: 0.7301 - recall: 0.7312 - val_loss: 0.5379 - val_acc: 0.7278 - val_precision: 0.7628 - val_recall: 0.6611 - lr: 0.0010
Epoch 10/12
1046/1050 [============================>.] - ETA: 0s - loss: 0.5417 - acc: 0.7328 - precision: 0.7332 - recall: 0.7304
Epoch 10: val_acc did not improve from 0.74778
1050/1050 [==============================] - 16s 16ms/step - loss: 0.5418 - acc: 0.7326 - precision: 0.7336 - recall: 0.7305 - val_loss: 0.5494 - val_acc: 0.7289 - val_precision: 0.6843 - val_recall: 0.8500 - lr: 0.0010
Epoch 11/12
1043/1050 [============================>.] - ETA: 0s - loss: 0.5392 - acc: 0.7373 - precision: 0.7349 - recall: 0.7416
Epoch 11: val_acc did not improve from 0.74778
1050/1050 [==============================] - 15s 14ms/step - loss: 0.5396 - acc: 0.7370 - precision: 0.7348 - recall: 0.7417 - val_loss: 0.5451 - val_acc: 0.7178 - val_precision: 0.6888 - val_recall: 0.7944 - lr: 0.0010
Epoch 12/12
1047/1050 [============================>.] - ETA: 0s - loss: 0.5405 - acc: 0.7328 - precision: 0.7332 - recall: 0.7329
Epoch 12: val_acc did not improve from 0.74778
1050/1050 [==============================] - 15s 14ms/step - loss: 0.5404 - acc: 0.7329 - precision: 0.7329 - recall: 0.7329 - val_loss: 0.5609 - val_acc: 0.7378 - val_precision: 0.7616 - val_recall: 0.6922 - lr: 0.0010
57/57 [==============================] - 0s 2ms/step
--------------------------------------------------------------------------------
Classification Matrix
--------------------------------------------------------------------------------
precision recall f1-score support
Normal (Class 0) 0.76 0.74 0.75 900
Pneumonia (Class 1) 0.75 0.77 0.76 900
accuracy 0.76 1800
macro avg 0.76 0.76 0.76 1800
weighted avg 0.76 0.76 0.76 1800
--------------------------------------------------------------------------------
<Figure size 640x480 with 0 Axes>
Observation
Even after using Hyperparameter tuning with Grid Search, there is not much improvement seen in CNN model's performance. The accuracy and precision is still around 76%, almost same as Base CNN Model performance.
If any two models are developed to perform similar tasks, then generalised knowledge can be shared between them. This approach to machine learning development reduces the resources and amount of labelled data required to train new models. It is becoming an important part of the evolution of machine learning and is increasingly used as a technique within the development process.
Transfer learning for machine learning is when elements of a pre-trained model are reused in a new machine learning model. Transfer models can be tried to compare model performance.
Limitations of Grid Search
The main problem with grid search is that it takes a lot of time and computing power. Since it checks every possible combination of settings, it can mean evaluating many models, especially when there are a lot of settings to play with and a wide range of values for each one. This can make finding the best settings drag on and on, making it too slow for some models and data.
When choosing the search space for Grid Search, data scientists usually reflect on their previous successful hyperparameter tuning jobs and tend to repeatedly choose the same parameters and ranges for different projects. As a result, Grid Search inherits the users’ bias in their perception of the optimal search space for the best hyperparameters. On the other hand, expanding the search space further will exponentially increase the processing time for Grid Search. Ex: What if the best hyperparameters for the model are not even in your search space? What if the best max_depth for that XGBoost model is 9, but you searched over [4, 5, 6, 7]?
One of the major drawbacks of grid search is that when it comes to dimensionality, it suffers when the number of hyperparameters grows exponentially. With as few as four parameters this problem can become impractical, because the number of evaluations required for this strategy increases exponentially with each additional parameter, due to the curse of dimensionality.
Source Data
Before feeding the images into the models, we conducted the following preprocessing steps:
Model Architectures
We experimented with five pre-trained deep learning models, each loaded with pre-trained weights from ImageNet:
ResNet50
ResNet50 is a convolutional neural network (CNN) architecture with 50 layers. It is known for its deep structure and skip connections, which help alleviate the vanishing gradient problem. ResNet50 has been widely used in image classification tasks.
• Accuracy: 73%
• AUC: 73
• Precision (Class 0/1): 0.69 / 0.79
• Recall (Class 0/1): 0.84 / 0.62
• F1-score (Class 0/1): 0.76 / 0.70
ResNet101
ResNet101 is an extension of ResNet50, with even deeper architecture, consisting of 101 layers. It offers improved feature extraction capabilities and is known for its excellent performance on various image-related tasks.
• Accuracy: 52%
• AUC: 51.61
• Precision (Class 0/1): 0.51 / 0.61
• Recall (Class 0/1): 0.94 / 0.09
• F1-score (Class 0/1): 0.66 / 0.16
MobileNet
MobileNet is designed for efficient inference on mobile and embedded devices. It uses depthwise separable convolutions to reduce computational complexity while maintaining good performance. MobileNet is lightweight and suitable for resource-constrained environments.
• Accuracy: 78%
• AUC: 77.56
• Precision (Class 0/1): 0.81 / 0.75
• Recall (Class 0/1): 0.73 / 0.83
• F1-score (Class 0/1): 0.76 / 0.79
EfficientNetB0
EfficientNetB0 is part of the EfficientNet family, known for its superior efficiency and performance. It employs a compound scaling method to balance network depth, width, and resolution, resulting in models that achieve state-of-the-art results with fewer parameters.
• Accuracy: 74%
• AUC: 74.11
• Precision (Class 0/1): 0.81 / 0.70
• Recall (Class 0/1): 0.63 / 0.86
• F1-score (Class 0/1): 0.71 / 0.77
VGG19
VGG19 is a variant of the VGG (Visual Geometry Group) architecture. It has 19 layers with small (3x3) convolutional filters, making it deeper than the original VGG15. VGG networks are known for their simplicity and effectiveness in image classification tasks.
• Accuracy: 74%
• AUC: 50
• Precision (Class 0/1): 0.81 / 0.70
• Recall (Class 0/1): 0.63 / 0.86
• F1-score (Class 0/1): 0.71 / 0.77
Model Comparison
Accuracy: MobileNet achieved the highest accuracy at 78%, followed closely by EfficientNetB0 and VGG19, both at 74%. ResNet50 achieved 73% accuracy, while ResNet101 lagged behind with 52% accuracy.
AUC (Area Under the ROC Curve): MobileNet and EfficientNetB0 show the highest AUC scores of 77.56 and 74.11, respectively, indicating strong model performance. ResNet50 follows with an AUC of 73. ResNet101 and VGG19 perform less optimally, with AUC scores of 51.61 and 50, respectively.
Precision and Recall: MobileNet and EfficientNetB0 exhibit a balance between precision and recall for both classes, making them suitable for real-world deployment. ResNet50 shows competitive recall for Class 0 (normal) but relatively lower precision for Class 1 (pneumonia). ResNet101 has very high recall for Class 0 but significantly lower recall for Class 1. VGG19 has relatively high precision but lower recall for both classes.
F1-Score: MobileNet and EfficientNetB0 achieve the highest F1-scores for both Class 0 and Class 1, demonstrating their effectiveness in classifying both normal and pneumonia cases. ResNet50 shows balanced F1-scores but slightly lower performance compared to MobileNet and EfficientNetB0. ResNet101 and VGG19 exhibit lower F1-scores overall, indicating suboptimal performance.
Conclusion In conclusion, based on the comprehensive analysis of accuracy, AUC, precision, recall, and F1-score, MobileNet and EfficientNetB0 emerge as the top-performing models for pneumonia detection from chest X-ray images.
MobileNet achieves the highest accuracy and AUC, indicating excellent overall performance.
EfficientNetB0 closely follows with competitive metrics, including precision and recall.
These models offer a balance between correctly classifying normal and pneumonia cases, which is crucial for medical diagnosis. While both models perform exceptionally well, the choice between MobileNet and EfficientNetB0 could depend on factors like computational resources and deployment constraints. MobileNet might be preferable for resource-constrained environments, while EfficientNetB0 could be chosen for situations where computational resources are more abundant.
Training Strategy
The dataset was split into training (70%), validation (15%), and test (15%) sets. The models were trained using categorical cross-entropy loss and optimized with the Adam optimizer. An early stopping mechanism was implemented to prevent overfitting, and a learning rate reduction on a plateau was employed.
def read_and_resize_images_rgb(final_df):
resized_rgb_images = []
boxes = []
for i in range(len(final_df)):
patient_id = final_df['patientId'].iloc[i] # Access 'patientId' column
target = final_df['Target'].iloc[i] # Access 'Target' column
dicom_data = pydicom.read_file(os.path.join(IMAGE_PATH, '%s.dcm' % patient_id))
img = dicom_data.pixel_array
# Resize image to 32x32
img = cv2.resize(img, (32, 32))
# Convert grayscale image to RGB format
img_rgb = cv2.cvtColor(img, cv2.COLOR_GRAY2RGB)
resized_rgb_images.append(img_rgb)
boxes.append(np.array(target, dtype=np.float32))
return np.array(resized_rgb_images), np.array(boxes)
NUM_OF_EPOCHS = 12
FONT_SIZE = 10
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.metrics import confusion_matrix, classification_report, accuracy_score, precision_score, recall_score, f1_score
model_comparision_list = []
def evaluate_model_perf_tl(history, model, model_descr):
if 'acc' in history.history:
accuracy_key = 'acc'
elif 'accuracy' in history.history:
accuracy_key = 'accuracy'
else:
raise ValueError("Neither 'acc' nor 'accuracy' found in history.history.")
if 'val_acc' in history.history:
val_accuracy_key = 'val_acc'
elif 'val_accuracy' in history.history:
val_accuracy_key = 'val_accuracy'
else:
raise ValueError("Neither 'val_acc' nor 'val_accuracy' found in history.history.")
epochs = [i for i in range(len(history.history[accuracy_key]))]
fig = plt.figure(figsize=(16, 5))
plt.subplot(1, 3, 1)
plt.plot(epochs, history.history[accuracy_key], marker='o', color='orange', label='Training Accuracy')
plt.plot(epochs, history.history[val_accuracy_key], marker='o', color='turquoise', label='Validation Accuracy')
plt.title('Training & Validation Accuracy')
plt.legend(fontsize=FONT_SIZE)
plt.xticks(fontsize=FONT_SIZE)
plt.yticks(fontsize=FONT_SIZE)
plt.xlabel("Epochs", size=FONT_SIZE)
plt.ylabel("Accuracy", size=FONT_SIZE)
plt.subplot(1, 3, 2)
plt.plot(epochs, history.history['loss'], marker='o', color='orange', label='Training Loss')
plt.plot(epochs, history.history['val_loss'], marker='o', color='turquoise', label='Validation Loss')
plt.title('Testing Accuracy & Loss')
plt.xticks(fontsize=FONT_SIZE)
plt.yticks(fontsize=FONT_SIZE)
plt.legend(fontsize=FONT_SIZE)
plt.xlabel("Epochs", size=FONT_SIZE)
plt.ylabel("Training & Validation Loss", size=FONT_SIZE)
# Calculate y_pred based on the validation set
y_pred = get_model_prediction(model)
## CONFUSION MATRIX
plt.subplot(1, 3, 3)
# Set up the labels for the confusion matrix
cm = confusion_matrix(y_test, y_pred)
labels = ['NORMAL', 'PNEUMONIA']
ax = sns.heatmap(cm, annot=True, fmt='d', cmap="GnBu", annot_kws={"fontsize": FONT_SIZE},
xticklabels=labels, yticklabels=labels)
ax.set(ylabel="True Label", xlabel="Predicted Label")
plt.title('Confusion Matrix')
plt.show()
plt.tight_layout()
print('\n\n\n')
print('--' * 40)
print("Classification Matrix")
print('--' * 40)
print(classification_report(y_test, y_pred,
target_names=['Normal (Class 0)', 'Pneumonia (Class 1)']))
print('--' * 40)
# performance_matrix list of this model
performance_matrix = []
performance_matrix.append(model_descr)
performance_matrix.append(accuracy_score(y_test, y_pred) * 100)
performance_matrix.append(precision_score(y_test, y_pred, average='macro') * 100)
performance_matrix.append(recall_score(y_test, y_pred, average='macro') * 100)
performance_matrix.append(f1_score(y_test, y_pred, average='macro') * 100)
# Store the performance per model
model_comparision_list.append(performance_matrix)
# Read and resize training, validation and test images
X_train, y_train = read_and_resize_images_rgb(train)
X_val, y_val = read_and_resize_images_rgb(val)
X_test, y_test = read_and_resize_images_rgb(test)
X_train = np.array(X_train) / 255
X_val = np.array(X_val) / 255
X_test = np.array(X_test) / 255
# Checking the shape of train, test and validation sets
print('Shape of Training Data X: ', X_train.shape,'Y: ',y_train.shape )
print('Shape of Testing Data X: ', X_test.shape,'Y: ',y_test.shape)
print('Shape of Validation Data X: ', X_val.shape,'Y: ',y_val.shape)
Shape of Training Data X: (8400, 32, 32, 3) Y: (8400,) Shape of Testing Data X: (1800, 32, 32, 3) Y: (1800,) Shape of Validation Data X: (1800, 32, 32, 3) Y: (1800,)
def fit_model_tl(model):
history = model.fit(train_generator, epochs = NUM_OF_EPOCHS,
validation_data = valid_generator,
callbacks=[checkpoint,early_stopping,learning_rate_reduction],
batch_size=batch_size ,use_multiprocessing=True)
return history
batch_size = 8
# Establish our metrics
METRICS = ['acc',
tf.keras.metrics.Precision(name='precision'),
tf.keras.metrics.Recall(name='recall')]
learning_rate_reduction = ReduceLROnPlateau(monitor='val_accuracy', patience = 2, verbose=1,factor=0.3, min_lr=0.000001)
early_stopping = EarlyStopping(monitor='val_loss',patience=5, restore_best_weights=True)
# Callbacks to reduce learning rate timely after monitoring a quantit
filepath="/kaggle/working/weights.hdf5"
checkpoint = ModelCheckpoint(filepath, monitor='val_acc', verbose=1, save_best_only=True, mode='max')
train_datagen = ImageDataGenerator(
featurewise_center=False, # set input mean to 0 over the dataset
samplewise_center=False, # set each sample mean to 0
featurewise_std_normalization=False, # divide inputs by std of the dataset
samplewise_std_normalization=False, # divide each input by its std
zca_whitening=False, # apply ZCA whitening
rotation_range = 30, # randomly rotate images in the range (degrees, 0 to 180)
zoom_range = 0.2, # Randomly zoom image
width_shift_range=0.1, # randomly shift images horizontally (fraction of total width)
height_shift_range=0.1, # randomly shift images vertically (fraction of total height)
horizontal_flip = True, # randomly flip images
vertical_flip=False) # randomly flip images
train_datagen.fit(X_train)
test_datagen = ImageDataGenerator()
train_generator = train_datagen.flow(X_train, y_train, batch_size=batch_size)
valid_generator = train_datagen.flow(X_val, y_val, batch_size=batch_size)
test_generator = test_datagen.flow(X_test, y_test, batch_size=1)
def get_model_prediction(model):
# Predict the values from the validation dataset
predictions = model.predict(X_test)
# Convert predictions classes to one hot vectors
return predictions.round().astype(int).tolist()
def fit_model(model):
history = model.fit(train_generator, epochs = NUM_OF_EPOCHS,
validation_data = valid_generator,
callbacks=[checkpoint,early_stopping,learning_rate_reduction],
batch_size=batch_size ,use_multiprocessing=True)
return history
from keras.applications import ResNet50, ResNet101, InceptionV3, MobileNet, EfficientNetB0, VGG19
from keras.layers import Input, Dense, GlobalAveragePooling2D, Dropout, Lambda
from keras.models import Model
import tensorflow as tf
# Define the metrics you want to use
METRICS = ['accuracy']
def create_model(input_shape, base_model, model_name):
# Load the base model with pre-trained weights
base_model = base_model(input_shape=input_shape, include_top=False, weights='imagenet')
x = base_model.output
x = GlobalAveragePooling2D()(x)
x = Dense(512, activation='relu')(x)
x = Dropout(0.5)(x)
output_layer = Dense(1, activation='sigmoid')(x)
# Create the transfer learning model
model = Model(inputs=base_model.input, outputs=output_layer)
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=METRICS)
model.summary()
return model
def create_model_6():
return create_model((32, 32, 3), MobileNet, "MobileNet")
def create_model_7():
return create_model((32, 32, 3), EfficientNetB0, "EfficientNetB0")
model_6 = create_model_6()
history_6 = fit_model_tl(model_6)
evaluate_model_perf_tl(history_6, model_6, "MobileNet")
Model: "model_2"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_3 (InputLayer) [(None, 32, 32, 3)] 0
conv1 (Conv2D) (None, 16, 16, 32) 864
conv1_bn (BatchNormalizatio (None, 16, 16, 32) 128
n)
conv1_relu (ReLU) (None, 16, 16, 32) 0
conv_dw_1 (DepthwiseConv2D) (None, 16, 16, 32) 288
conv_dw_1_bn (BatchNormaliz (None, 16, 16, 32) 128
ation)
conv_dw_1_relu (ReLU) (None, 16, 16, 32) 0
conv_pw_1 (Conv2D) (None, 16, 16, 64) 2048
conv_pw_1_bn (BatchNormaliz (None, 16, 16, 64) 256
ation)
conv_pw_1_relu (ReLU) (None, 16, 16, 64) 0
conv_pad_2 (ZeroPadding2D) (None, 17, 17, 64) 0
conv_dw_2 (DepthwiseConv2D) (None, 8, 8, 64) 576
conv_dw_2_bn (BatchNormaliz (None, 8, 8, 64) 256
ation)
conv_dw_2_relu (ReLU) (None, 8, 8, 64) 0
conv_pw_2 (Conv2D) (None, 8, 8, 128) 8192
conv_pw_2_bn (BatchNormaliz (None, 8, 8, 128) 512
ation)
conv_pw_2_relu (ReLU) (None, 8, 8, 128) 0
conv_dw_3 (DepthwiseConv2D) (None, 8, 8, 128) 1152
conv_dw_3_bn (BatchNormaliz (None, 8, 8, 128) 512
ation)
conv_dw_3_relu (ReLU) (None, 8, 8, 128) 0
conv_pw_3 (Conv2D) (None, 8, 8, 128) 16384
conv_pw_3_bn (BatchNormaliz (None, 8, 8, 128) 512
ation)
conv_pw_3_relu (ReLU) (None, 8, 8, 128) 0
conv_pad_4 (ZeroPadding2D) (None, 9, 9, 128) 0
conv_dw_4 (DepthwiseConv2D) (None, 4, 4, 128) 1152
conv_dw_4_bn (BatchNormaliz (None, 4, 4, 128) 512
ation)
conv_dw_4_relu (ReLU) (None, 4, 4, 128) 0
conv_pw_4 (Conv2D) (None, 4, 4, 256) 32768
conv_pw_4_bn (BatchNormaliz (None, 4, 4, 256) 1024
ation)
conv_pw_4_relu (ReLU) (None, 4, 4, 256) 0
conv_dw_5 (DepthwiseConv2D) (None, 4, 4, 256) 2304
conv_dw_5_bn (BatchNormaliz (None, 4, 4, 256) 1024
ation)
conv_dw_5_relu (ReLU) (None, 4, 4, 256) 0
conv_pw_5 (Conv2D) (None, 4, 4, 256) 65536
conv_pw_5_bn (BatchNormaliz (None, 4, 4, 256) 1024
ation)
conv_pw_5_relu (ReLU) (None, 4, 4, 256) 0
conv_pad_6 (ZeroPadding2D) (None, 5, 5, 256) 0
conv_dw_6 (DepthwiseConv2D) (None, 2, 2, 256) 2304
conv_dw_6_bn (BatchNormaliz (None, 2, 2, 256) 1024
ation)
conv_dw_6_relu (ReLU) (None, 2, 2, 256) 0
conv_pw_6 (Conv2D) (None, 2, 2, 512) 131072
conv_pw_6_bn (BatchNormaliz (None, 2, 2, 512) 2048
ation)
conv_pw_6_relu (ReLU) (None, 2, 2, 512) 0
conv_dw_7 (DepthwiseConv2D) (None, 2, 2, 512) 4608
conv_dw_7_bn (BatchNormaliz (None, 2, 2, 512) 2048
ation)
conv_dw_7_relu (ReLU) (None, 2, 2, 512) 0
conv_pw_7 (Conv2D) (None, 2, 2, 512) 262144
conv_pw_7_bn (BatchNormaliz (None, 2, 2, 512) 2048
ation)
conv_pw_7_relu (ReLU) (None, 2, 2, 512) 0
conv_dw_8 (DepthwiseConv2D) (None, 2, 2, 512) 4608
conv_dw_8_bn (BatchNormaliz (None, 2, 2, 512) 2048
ation)
conv_dw_8_relu (ReLU) (None, 2, 2, 512) 0
conv_pw_8 (Conv2D) (None, 2, 2, 512) 262144
conv_pw_8_bn (BatchNormaliz (None, 2, 2, 512) 2048
ation)
conv_pw_8_relu (ReLU) (None, 2, 2, 512) 0
conv_dw_9 (DepthwiseConv2D) (None, 2, 2, 512) 4608
conv_dw_9_bn (BatchNormaliz (None, 2, 2, 512) 2048
ation)
conv_dw_9_relu (ReLU) (None, 2, 2, 512) 0
conv_pw_9 (Conv2D) (None, 2, 2, 512) 262144
conv_pw_9_bn (BatchNormaliz (None, 2, 2, 512) 2048
ation)
conv_pw_9_relu (ReLU) (None, 2, 2, 512) 0
conv_dw_10 (DepthwiseConv2D (None, 2, 2, 512) 4608
)
conv_dw_10_bn (BatchNormali (None, 2, 2, 512) 2048
zation)
conv_dw_10_relu (ReLU) (None, 2, 2, 512) 0
conv_pw_10 (Conv2D) (None, 2, 2, 512) 262144
conv_pw_10_bn (BatchNormali (None, 2, 2, 512) 2048
zation)
conv_pw_10_relu (ReLU) (None, 2, 2, 512) 0
conv_dw_11 (DepthwiseConv2D (None, 2, 2, 512) 4608
)
conv_dw_11_bn (BatchNormali (None, 2, 2, 512) 2048
zation)
conv_dw_11_relu (ReLU) (None, 2, 2, 512) 0
conv_pw_11 (Conv2D) (None, 2, 2, 512) 262144
conv_pw_11_bn (BatchNormali (None, 2, 2, 512) 2048
zation)
conv_pw_11_relu (ReLU) (None, 2, 2, 512) 0
conv_pad_12 (ZeroPadding2D) (None, 3, 3, 512) 0
conv_dw_12 (DepthwiseConv2D (None, 1, 1, 512) 4608
)
conv_dw_12_bn (BatchNormali (None, 1, 1, 512) 2048
zation)
conv_dw_12_relu (ReLU) (None, 1, 1, 512) 0
conv_pw_12 (Conv2D) (None, 1, 1, 1024) 524288
conv_pw_12_bn (BatchNormali (None, 1, 1, 1024) 4096
zation)
conv_pw_12_relu (ReLU) (None, 1, 1, 1024) 0
conv_dw_13 (DepthwiseConv2D (None, 1, 1, 1024) 9216
)
conv_dw_13_bn (BatchNormali (None, 1, 1, 1024) 4096
zation)
conv_dw_13_relu (ReLU) (None, 1, 1, 1024) 0
conv_pw_13 (Conv2D) (None, 1, 1, 1024) 1048576
conv_pw_13_bn (BatchNormali (None, 1, 1, 1024) 4096
zation)
conv_pw_13_relu (ReLU) (None, 1, 1, 1024) 0
global_average_pooling2d_2 (None, 1024) 0
(GlobalAveragePooling2D)
dense_4 (Dense) (None, 512) 524800
dropout_2 (Dropout) (None, 512) 0
dense_5 (Dense) (None, 1) 513
=================================================================
Total params: 3,754,177
Trainable params: 3,732,289
Non-trainable params: 21,888
_________________________________________________________________
Epoch 1/12
1049/1050 [============================>.] - ETA: 0s - loss: 0.7742 - acc: 0.6444 - precision: 0.6448 - recall: 0.6432
Epoch 1: val_acc improved from -inf to 0.72278, saving model to /kaggle/working/weights.hdf5
1050/1050 [==============================] - 48s 31ms/step - loss: 0.7741 - acc: 0.6443 - precision: 0.6446 - recall: 0.6431 - val_loss: 0.5652 - val_acc: 0.7228 - val_precision: 0.7135 - val_recall: 0.7444 - lr: 0.0010
Epoch 2/12
1049/1050 [============================>.] - ETA: 0s - loss: 0.6185 - acc: 0.6939 - precision: 0.6881 - recall: 0.7092
Epoch 2: val_acc did not improve from 0.72278
1050/1050 [==============================] - 31s 29ms/step - loss: 0.6183 - acc: 0.6939 - precision: 0.6881 - recall: 0.7093 - val_loss: 0.5771 - val_acc: 0.7156 - val_precision: 0.6732 - val_recall: 0.8378 - lr: 0.0010
Epoch 3/12
1048/1050 [============================>.] - ETA: 0s - loss: 0.6064 - acc: 0.6865 - precision: 0.6643 - recall: 0.7546
Epoch 3: val_acc did not improve from 0.72278
1050/1050 [==============================] - 31s 30ms/step - loss: 0.6062 - acc: 0.6865 - precision: 0.6642 - recall: 0.7548 - val_loss: 0.5969 - val_acc: 0.7100 - val_precision: 0.6687 - val_recall: 0.8322 - lr: 0.0010
Epoch 4/12
1049/1050 [============================>.] - ETA: 0s - loss: 0.6047 - acc: 0.6781 - precision: 0.6520 - recall: 0.7643
Epoch 4: val_acc did not improve from 0.72278
1050/1050 [==============================] - 31s 30ms/step - loss: 0.6047 - acc: 0.6781 - precision: 0.6519 - recall: 0.7643 - val_loss: 0.5965 - val_acc: 0.7100 - val_precision: 0.6828 - val_recall: 0.7844 - lr: 0.0010
Epoch 5/12
1050/1050 [==============================] - ETA: 0s - loss: 0.6108 - acc: 0.6854 - precision: 0.6649 - recall: 0.7474
Epoch 5: val_acc did not improve from 0.72278
1050/1050 [==============================] - 32s 31ms/step - loss: 0.6108 - acc: 0.6854 - precision: 0.6649 - recall: 0.7474 - val_loss: 0.6125 - val_acc: 0.6961 - val_precision: 0.6833 - val_recall: 0.7311 - lr: 0.0010
Epoch 6/12
1048/1050 [============================>.] - ETA: 0s - loss: 0.6238 - acc: 0.6534 - precision: 0.6305 - recall: 0.7429
Epoch 6: val_acc did not improve from 0.72278
1050/1050 [==============================] - 32s 30ms/step - loss: 0.6241 - acc: 0.6531 - precision: 0.6298 - recall: 0.7429 - val_loss: 0.6380 - val_acc: 0.5722 - val_precision: 0.5448 - val_recall: 0.8789 - lr: 0.0010
57/57 [==============================] - 1s 4ms/step
--------------------------------------------------------------------------------
Classification Matrix
--------------------------------------------------------------------------------
precision recall f1-score support
Normal (Class 0) 0.76 0.66 0.71 900
Pneumonia (Class 1) 0.70 0.79 0.74 900
accuracy 0.73 1800
macro avg 0.73 0.73 0.72 1800
weighted avg 0.73 0.73 0.72 1800
--------------------------------------------------------------------------------
<Figure size 640x480 with 0 Axes>
import tensorflow as tf
tf.config.optimizer.set_experimental_options({'layout_optimizer': False})
model_7 = create_model_7()
history_7 = fit_model_tl(model_7)
evaluate_model_perf_tl(history_7, model_7, 'EfficientNetB0')
Model: "model_4"
__________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
==================================================================================================
input_5 (InputLayer) [(None, 32, 32, 3)] 0 []
rescaling_2 (Rescaling) (None, 32, 32, 3) 0 ['input_5[0][0]']
normalization_1 (Normalization (None, 32, 32, 3) 7 ['rescaling_2[0][0]']
)
rescaling_3 (Rescaling) (None, 32, 32, 3) 0 ['normalization_1[0][0]']
stem_conv_pad (ZeroPadding2D) (None, 33, 33, 3) 0 ['rescaling_3[0][0]']
stem_conv (Conv2D) (None, 16, 16, 32) 864 ['stem_conv_pad[0][0]']
stem_bn (BatchNormalization) (None, 16, 16, 32) 128 ['stem_conv[0][0]']
stem_activation (Activation) (None, 16, 16, 32) 0 ['stem_bn[0][0]']
block1a_dwconv (DepthwiseConv2 (None, 16, 16, 32) 288 ['stem_activation[0][0]']
D)
block1a_bn (BatchNormalization (None, 16, 16, 32) 128 ['block1a_dwconv[0][0]']
)
block1a_activation (Activation (None, 16, 16, 32) 0 ['block1a_bn[0][0]']
)
block1a_se_squeeze (GlobalAver (None, 32) 0 ['block1a_activation[0][0]']
agePooling2D)
block1a_se_reshape (Reshape) (None, 1, 1, 32) 0 ['block1a_se_squeeze[0][0]']
block1a_se_reduce (Conv2D) (None, 1, 1, 8) 264 ['block1a_se_reshape[0][0]']
block1a_se_expand (Conv2D) (None, 1, 1, 32) 288 ['block1a_se_reduce[0][0]']
block1a_se_excite (Multiply) (None, 16, 16, 32) 0 ['block1a_activation[0][0]',
'block1a_se_expand[0][0]']
block1a_project_conv (Conv2D) (None, 16, 16, 16) 512 ['block1a_se_excite[0][0]']
block1a_project_bn (BatchNorma (None, 16, 16, 16) 64 ['block1a_project_conv[0][0]']
lization)
block2a_expand_conv (Conv2D) (None, 16, 16, 96) 1536 ['block1a_project_bn[0][0]']
block2a_expand_bn (BatchNormal (None, 16, 16, 96) 384 ['block2a_expand_conv[0][0]']
ization)
block2a_expand_activation (Act (None, 16, 16, 96) 0 ['block2a_expand_bn[0][0]']
ivation)
block2a_dwconv_pad (ZeroPaddin (None, 17, 17, 96) 0 ['block2a_expand_activation[0][0]
g2D) ']
block2a_dwconv (DepthwiseConv2 (None, 8, 8, 96) 864 ['block2a_dwconv_pad[0][0]']
D)
block2a_bn (BatchNormalization (None, 8, 8, 96) 384 ['block2a_dwconv[0][0]']
)
block2a_activation (Activation (None, 8, 8, 96) 0 ['block2a_bn[0][0]']
)
block2a_se_squeeze (GlobalAver (None, 96) 0 ['block2a_activation[0][0]']
agePooling2D)
block2a_se_reshape (Reshape) (None, 1, 1, 96) 0 ['block2a_se_squeeze[0][0]']
block2a_se_reduce (Conv2D) (None, 1, 1, 4) 388 ['block2a_se_reshape[0][0]']
block2a_se_expand (Conv2D) (None, 1, 1, 96) 480 ['block2a_se_reduce[0][0]']
block2a_se_excite (Multiply) (None, 8, 8, 96) 0 ['block2a_activation[0][0]',
'block2a_se_expand[0][0]']
block2a_project_conv (Conv2D) (None, 8, 8, 24) 2304 ['block2a_se_excite[0][0]']
block2a_project_bn (BatchNorma (None, 8, 8, 24) 96 ['block2a_project_conv[0][0]']
lization)
block2b_expand_conv (Conv2D) (None, 8, 8, 144) 3456 ['block2a_project_bn[0][0]']
block2b_expand_bn (BatchNormal (None, 8, 8, 144) 576 ['block2b_expand_conv[0][0]']
ization)
block2b_expand_activation (Act (None, 8, 8, 144) 0 ['block2b_expand_bn[0][0]']
ivation)
block2b_dwconv (DepthwiseConv2 (None, 8, 8, 144) 1296 ['block2b_expand_activation[0][0]
D) ']
block2b_bn (BatchNormalization (None, 8, 8, 144) 576 ['block2b_dwconv[0][0]']
)
block2b_activation (Activation (None, 8, 8, 144) 0 ['block2b_bn[0][0]']
)
block2b_se_squeeze (GlobalAver (None, 144) 0 ['block2b_activation[0][0]']
agePooling2D)
block2b_se_reshape (Reshape) (None, 1, 1, 144) 0 ['block2b_se_squeeze[0][0]']
block2b_se_reduce (Conv2D) (None, 1, 1, 6) 870 ['block2b_se_reshape[0][0]']
block2b_se_expand (Conv2D) (None, 1, 1, 144) 1008 ['block2b_se_reduce[0][0]']
block2b_se_excite (Multiply) (None, 8, 8, 144) 0 ['block2b_activation[0][0]',
'block2b_se_expand[0][0]']
block2b_project_conv (Conv2D) (None, 8, 8, 24) 3456 ['block2b_se_excite[0][0]']
block2b_project_bn (BatchNorma (None, 8, 8, 24) 96 ['block2b_project_conv[0][0]']
lization)
block2b_drop (Dropout) (None, 8, 8, 24) 0 ['block2b_project_bn[0][0]']
block2b_add (Add) (None, 8, 8, 24) 0 ['block2b_drop[0][0]',
'block2a_project_bn[0][0]']
block3a_expand_conv (Conv2D) (None, 8, 8, 144) 3456 ['block2b_add[0][0]']
block3a_expand_bn (BatchNormal (None, 8, 8, 144) 576 ['block3a_expand_conv[0][0]']
ization)
block3a_expand_activation (Act (None, 8, 8, 144) 0 ['block3a_expand_bn[0][0]']
ivation)
block3a_dwconv_pad (ZeroPaddin (None, 11, 11, 144) 0 ['block3a_expand_activation[0][0]
g2D) ']
block3a_dwconv (DepthwiseConv2 (None, 4, 4, 144) 3600 ['block3a_dwconv_pad[0][0]']
D)
block3a_bn (BatchNormalization (None, 4, 4, 144) 576 ['block3a_dwconv[0][0]']
)
block3a_activation (Activation (None, 4, 4, 144) 0 ['block3a_bn[0][0]']
)
block3a_se_squeeze (GlobalAver (None, 144) 0 ['block3a_activation[0][0]']
agePooling2D)
block3a_se_reshape (Reshape) (None, 1, 1, 144) 0 ['block3a_se_squeeze[0][0]']
block3a_se_reduce (Conv2D) (None, 1, 1, 6) 870 ['block3a_se_reshape[0][0]']
block3a_se_expand (Conv2D) (None, 1, 1, 144) 1008 ['block3a_se_reduce[0][0]']
block3a_se_excite (Multiply) (None, 4, 4, 144) 0 ['block3a_activation[0][0]',
'block3a_se_expand[0][0]']
block3a_project_conv (Conv2D) (None, 4, 4, 40) 5760 ['block3a_se_excite[0][0]']
block3a_project_bn (BatchNorma (None, 4, 4, 40) 160 ['block3a_project_conv[0][0]']
lization)
block3b_expand_conv (Conv2D) (None, 4, 4, 240) 9600 ['block3a_project_bn[0][0]']
block3b_expand_bn (BatchNormal (None, 4, 4, 240) 960 ['block3b_expand_conv[0][0]']
ization)
block3b_expand_activation (Act (None, 4, 4, 240) 0 ['block3b_expand_bn[0][0]']
ivation)
block3b_dwconv (DepthwiseConv2 (None, 4, 4, 240) 6000 ['block3b_expand_activation[0][0]
D) ']
block3b_bn (BatchNormalization (None, 4, 4, 240) 960 ['block3b_dwconv[0][0]']
)
block3b_activation (Activation (None, 4, 4, 240) 0 ['block3b_bn[0][0]']
)
block3b_se_squeeze (GlobalAver (None, 240) 0 ['block3b_activation[0][0]']
agePooling2D)
block3b_se_reshape (Reshape) (None, 1, 1, 240) 0 ['block3b_se_squeeze[0][0]']
block3b_se_reduce (Conv2D) (None, 1, 1, 10) 2410 ['block3b_se_reshape[0][0]']
block3b_se_expand (Conv2D) (None, 1, 1, 240) 2640 ['block3b_se_reduce[0][0]']
block3b_se_excite (Multiply) (None, 4, 4, 240) 0 ['block3b_activation[0][0]',
'block3b_se_expand[0][0]']
block3b_project_conv (Conv2D) (None, 4, 4, 40) 9600 ['block3b_se_excite[0][0]']
block3b_project_bn (BatchNorma (None, 4, 4, 40) 160 ['block3b_project_conv[0][0]']
lization)
block3b_drop (Dropout) (None, 4, 4, 40) 0 ['block3b_project_bn[0][0]']
block3b_add (Add) (None, 4, 4, 40) 0 ['block3b_drop[0][0]',
'block3a_project_bn[0][0]']
block4a_expand_conv (Conv2D) (None, 4, 4, 240) 9600 ['block3b_add[0][0]']
block4a_expand_bn (BatchNormal (None, 4, 4, 240) 960 ['block4a_expand_conv[0][0]']
ization)
block4a_expand_activation (Act (None, 4, 4, 240) 0 ['block4a_expand_bn[0][0]']
ivation)
block4a_dwconv_pad (ZeroPaddin (None, 5, 5, 240) 0 ['block4a_expand_activation[0][0]
g2D) ']
block4a_dwconv (DepthwiseConv2 (None, 2, 2, 240) 2160 ['block4a_dwconv_pad[0][0]']
D)
block4a_bn (BatchNormalization (None, 2, 2, 240) 960 ['block4a_dwconv[0][0]']
)
block4a_activation (Activation (None, 2, 2, 240) 0 ['block4a_bn[0][0]']
)
block4a_se_squeeze (GlobalAver (None, 240) 0 ['block4a_activation[0][0]']
agePooling2D)
block4a_se_reshape (Reshape) (None, 1, 1, 240) 0 ['block4a_se_squeeze[0][0]']
block4a_se_reduce (Conv2D) (None, 1, 1, 10) 2410 ['block4a_se_reshape[0][0]']
block4a_se_expand (Conv2D) (None, 1, 1, 240) 2640 ['block4a_se_reduce[0][0]']
block4a_se_excite (Multiply) (None, 2, 2, 240) 0 ['block4a_activation[0][0]',
'block4a_se_expand[0][0]']
block4a_project_conv (Conv2D) (None, 2, 2, 80) 19200 ['block4a_se_excite[0][0]']
block4a_project_bn (BatchNorma (None, 2, 2, 80) 320 ['block4a_project_conv[0][0]']
lization)
block4b_expand_conv (Conv2D) (None, 2, 2, 480) 38400 ['block4a_project_bn[0][0]']
block4b_expand_bn (BatchNormal (None, 2, 2, 480) 1920 ['block4b_expand_conv[0][0]']
ization)
block4b_expand_activation (Act (None, 2, 2, 480) 0 ['block4b_expand_bn[0][0]']
ivation)
block4b_dwconv (DepthwiseConv2 (None, 2, 2, 480) 4320 ['block4b_expand_activation[0][0]
D) ']
block4b_bn (BatchNormalization (None, 2, 2, 480) 1920 ['block4b_dwconv[0][0]']
)
block4b_activation (Activation (None, 2, 2, 480) 0 ['block4b_bn[0][0]']
)
block4b_se_squeeze (GlobalAver (None, 480) 0 ['block4b_activation[0][0]']
agePooling2D)
block4b_se_reshape (Reshape) (None, 1, 1, 480) 0 ['block4b_se_squeeze[0][0]']
block4b_se_reduce (Conv2D) (None, 1, 1, 20) 9620 ['block4b_se_reshape[0][0]']
block4b_se_expand (Conv2D) (None, 1, 1, 480) 10080 ['block4b_se_reduce[0][0]']
block4b_se_excite (Multiply) (None, 2, 2, 480) 0 ['block4b_activation[0][0]',
'block4b_se_expand[0][0]']
block4b_project_conv (Conv2D) (None, 2, 2, 80) 38400 ['block4b_se_excite[0][0]']
block4b_project_bn (BatchNorma (None, 2, 2, 80) 320 ['block4b_project_conv[0][0]']
lization)
block4b_drop (Dropout) (None, 2, 2, 80) 0 ['block4b_project_bn[0][0]']
block4b_add (Add) (None, 2, 2, 80) 0 ['block4b_drop[0][0]',
'block4a_project_bn[0][0]']
block4c_expand_conv (Conv2D) (None, 2, 2, 480) 38400 ['block4b_add[0][0]']
block4c_expand_bn (BatchNormal (None, 2, 2, 480) 1920 ['block4c_expand_conv[0][0]']
ization)
block4c_expand_activation (Act (None, 2, 2, 480) 0 ['block4c_expand_bn[0][0]']
ivation)
block4c_dwconv (DepthwiseConv2 (None, 2, 2, 480) 4320 ['block4c_expand_activation[0][0]
D) ']
block4c_bn (BatchNormalization (None, 2, 2, 480) 1920 ['block4c_dwconv[0][0]']
)
block4c_activation (Activation (None, 2, 2, 480) 0 ['block4c_bn[0][0]']
)
block4c_se_squeeze (GlobalAver (None, 480) 0 ['block4c_activation[0][0]']
agePooling2D)
block4c_se_reshape (Reshape) (None, 1, 1, 480) 0 ['block4c_se_squeeze[0][0]']
block4c_se_reduce (Conv2D) (None, 1, 1, 20) 9620 ['block4c_se_reshape[0][0]']
block4c_se_expand (Conv2D) (None, 1, 1, 480) 10080 ['block4c_se_reduce[0][0]']
block4c_se_excite (Multiply) (None, 2, 2, 480) 0 ['block4c_activation[0][0]',
'block4c_se_expand[0][0]']
block4c_project_conv (Conv2D) (None, 2, 2, 80) 38400 ['block4c_se_excite[0][0]']
block4c_project_bn (BatchNorma (None, 2, 2, 80) 320 ['block4c_project_conv[0][0]']
lization)
block4c_drop (Dropout) (None, 2, 2, 80) 0 ['block4c_project_bn[0][0]']
block4c_add (Add) (None, 2, 2, 80) 0 ['block4c_drop[0][0]',
'block4b_add[0][0]']
block5a_expand_conv (Conv2D) (None, 2, 2, 480) 38400 ['block4c_add[0][0]']
block5a_expand_bn (BatchNormal (None, 2, 2, 480) 1920 ['block5a_expand_conv[0][0]']
ization)
block5a_expand_activation (Act (None, 2, 2, 480) 0 ['block5a_expand_bn[0][0]']
ivation)
block5a_dwconv (DepthwiseConv2 (None, 2, 2, 480) 12000 ['block5a_expand_activation[0][0]
D) ']
block5a_bn (BatchNormalization (None, 2, 2, 480) 1920 ['block5a_dwconv[0][0]']
)
block5a_activation (Activation (None, 2, 2, 480) 0 ['block5a_bn[0][0]']
)
block5a_se_squeeze (GlobalAver (None, 480) 0 ['block5a_activation[0][0]']
agePooling2D)
block5a_se_reshape (Reshape) (None, 1, 1, 480) 0 ['block5a_se_squeeze[0][0]']
block5a_se_reduce (Conv2D) (None, 1, 1, 20) 9620 ['block5a_se_reshape[0][0]']
block5a_se_expand (Conv2D) (None, 1, 1, 480) 10080 ['block5a_se_reduce[0][0]']
block5a_se_excite (Multiply) (None, 2, 2, 480) 0 ['block5a_activation[0][0]',
'block5a_se_expand[0][0]']
block5a_project_conv (Conv2D) (None, 2, 2, 112) 53760 ['block5a_se_excite[0][0]']
block5a_project_bn (BatchNorma (None, 2, 2, 112) 448 ['block5a_project_conv[0][0]']
lization)
block5b_expand_conv (Conv2D) (None, 2, 2, 672) 75264 ['block5a_project_bn[0][0]']
block5b_expand_bn (BatchNormal (None, 2, 2, 672) 2688 ['block5b_expand_conv[0][0]']
ization)
block5b_expand_activation (Act (None, 2, 2, 672) 0 ['block5b_expand_bn[0][0]']
ivation)
block5b_dwconv (DepthwiseConv2 (None, 2, 2, 672) 16800 ['block5b_expand_activation[0][0]
D) ']
block5b_bn (BatchNormalization (None, 2, 2, 672) 2688 ['block5b_dwconv[0][0]']
)
block5b_activation (Activation (None, 2, 2, 672) 0 ['block5b_bn[0][0]']
)
block5b_se_squeeze (GlobalAver (None, 672) 0 ['block5b_activation[0][0]']
agePooling2D)
block5b_se_reshape (Reshape) (None, 1, 1, 672) 0 ['block5b_se_squeeze[0][0]']
block5b_se_reduce (Conv2D) (None, 1, 1, 28) 18844 ['block5b_se_reshape[0][0]']
block5b_se_expand (Conv2D) (None, 1, 1, 672) 19488 ['block5b_se_reduce[0][0]']
block5b_se_excite (Multiply) (None, 2, 2, 672) 0 ['block5b_activation[0][0]',
'block5b_se_expand[0][0]']
block5b_project_conv (Conv2D) (None, 2, 2, 112) 75264 ['block5b_se_excite[0][0]']
block5b_project_bn (BatchNorma (None, 2, 2, 112) 448 ['block5b_project_conv[0][0]']
lization)
block5b_drop (Dropout) (None, 2, 2, 112) 0 ['block5b_project_bn[0][0]']
block5b_add (Add) (None, 2, 2, 112) 0 ['block5b_drop[0][0]',
'block5a_project_bn[0][0]']
block5c_expand_conv (Conv2D) (None, 2, 2, 672) 75264 ['block5b_add[0][0]']
block5c_expand_bn (BatchNormal (None, 2, 2, 672) 2688 ['block5c_expand_conv[0][0]']
ization)
block5c_expand_activation (Act (None, 2, 2, 672) 0 ['block5c_expand_bn[0][0]']
ivation)
block5c_dwconv (DepthwiseConv2 (None, 2, 2, 672) 16800 ['block5c_expand_activation[0][0]
D) ']
block5c_bn (BatchNormalization (None, 2, 2, 672) 2688 ['block5c_dwconv[0][0]']
)
block5c_activation (Activation (None, 2, 2, 672) 0 ['block5c_bn[0][0]']
)
block5c_se_squeeze (GlobalAver (None, 672) 0 ['block5c_activation[0][0]']
agePooling2D)
block5c_se_reshape (Reshape) (None, 1, 1, 672) 0 ['block5c_se_squeeze[0][0]']
block5c_se_reduce (Conv2D) (None, 1, 1, 28) 18844 ['block5c_se_reshape[0][0]']
block5c_se_expand (Conv2D) (None, 1, 1, 672) 19488 ['block5c_se_reduce[0][0]']
block5c_se_excite (Multiply) (None, 2, 2, 672) 0 ['block5c_activation[0][0]',
'block5c_se_expand[0][0]']
block5c_project_conv (Conv2D) (None, 2, 2, 112) 75264 ['block5c_se_excite[0][0]']
block5c_project_bn (BatchNorma (None, 2, 2, 112) 448 ['block5c_project_conv[0][0]']
lization)
block5c_drop (Dropout) (None, 2, 2, 112) 0 ['block5c_project_bn[0][0]']
block5c_add (Add) (None, 2, 2, 112) 0 ['block5c_drop[0][0]',
'block5b_add[0][0]']
block6a_expand_conv (Conv2D) (None, 2, 2, 672) 75264 ['block5c_add[0][0]']
block6a_expand_bn (BatchNormal (None, 2, 2, 672) 2688 ['block6a_expand_conv[0][0]']
ization)
block6a_expand_activation (Act (None, 2, 2, 672) 0 ['block6a_expand_bn[0][0]']
ivation)
block6a_dwconv_pad (ZeroPaddin (None, 5, 5, 672) 0 ['block6a_expand_activation[0][0]
g2D) ']
block6a_dwconv (DepthwiseConv2 (None, 1, 1, 672) 16800 ['block6a_dwconv_pad[0][0]']
D)
block6a_bn (BatchNormalization (None, 1, 1, 672) 2688 ['block6a_dwconv[0][0]']
)
block6a_activation (Activation (None, 1, 1, 672) 0 ['block6a_bn[0][0]']
)
block6a_se_squeeze (GlobalAver (None, 672) 0 ['block6a_activation[0][0]']
agePooling2D)
block6a_se_reshape (Reshape) (None, 1, 1, 672) 0 ['block6a_se_squeeze[0][0]']
block6a_se_reduce (Conv2D) (None, 1, 1, 28) 18844 ['block6a_se_reshape[0][0]']
block6a_se_expand (Conv2D) (None, 1, 1, 672) 19488 ['block6a_se_reduce[0][0]']
block6a_se_excite (Multiply) (None, 1, 1, 672) 0 ['block6a_activation[0][0]',
'block6a_se_expand[0][0]']
block6a_project_conv (Conv2D) (None, 1, 1, 192) 129024 ['block6a_se_excite[0][0]']
block6a_project_bn (BatchNorma (None, 1, 1, 192) 768 ['block6a_project_conv[0][0]']
lization)
block6b_expand_conv (Conv2D) (None, 1, 1, 1152) 221184 ['block6a_project_bn[0][0]']
block6b_expand_bn (BatchNormal (None, 1, 1, 1152) 4608 ['block6b_expand_conv[0][0]']
ization)
block6b_expand_activation (Act (None, 1, 1, 1152) 0 ['block6b_expand_bn[0][0]']
ivation)
block6b_dwconv (DepthwiseConv2 (None, 1, 1, 1152) 28800 ['block6b_expand_activation[0][0]
D) ']
block6b_bn (BatchNormalization (None, 1, 1, 1152) 4608 ['block6b_dwconv[0][0]']
)
block6b_activation (Activation (None, 1, 1, 1152) 0 ['block6b_bn[0][0]']
)
block6b_se_squeeze (GlobalAver (None, 1152) 0 ['block6b_activation[0][0]']
agePooling2D)
block6b_se_reshape (Reshape) (None, 1, 1, 1152) 0 ['block6b_se_squeeze[0][0]']
block6b_se_reduce (Conv2D) (None, 1, 1, 48) 55344 ['block6b_se_reshape[0][0]']
block6b_se_expand (Conv2D) (None, 1, 1, 1152) 56448 ['block6b_se_reduce[0][0]']
block6b_se_excite (Multiply) (None, 1, 1, 1152) 0 ['block6b_activation[0][0]',
'block6b_se_expand[0][0]']
block6b_project_conv (Conv2D) (None, 1, 1, 192) 221184 ['block6b_se_excite[0][0]']
block6b_project_bn (BatchNorma (None, 1, 1, 192) 768 ['block6b_project_conv[0][0]']
lization)
block6b_drop (Dropout) (None, 1, 1, 192) 0 ['block6b_project_bn[0][0]']
block6b_add (Add) (None, 1, 1, 192) 0 ['block6b_drop[0][0]',
'block6a_project_bn[0][0]']
block6c_expand_conv (Conv2D) (None, 1, 1, 1152) 221184 ['block6b_add[0][0]']
block6c_expand_bn (BatchNormal (None, 1, 1, 1152) 4608 ['block6c_expand_conv[0][0]']
ization)
block6c_expand_activation (Act (None, 1, 1, 1152) 0 ['block6c_expand_bn[0][0]']
ivation)
block6c_dwconv (DepthwiseConv2 (None, 1, 1, 1152) 28800 ['block6c_expand_activation[0][0]
D) ']
block6c_bn (BatchNormalization (None, 1, 1, 1152) 4608 ['block6c_dwconv[0][0]']
)
block6c_activation (Activation (None, 1, 1, 1152) 0 ['block6c_bn[0][0]']
)
block6c_se_squeeze (GlobalAver (None, 1152) 0 ['block6c_activation[0][0]']
agePooling2D)
block6c_se_reshape (Reshape) (None, 1, 1, 1152) 0 ['block6c_se_squeeze[0][0]']
block6c_se_reduce (Conv2D) (None, 1, 1, 48) 55344 ['block6c_se_reshape[0][0]']
block6c_se_expand (Conv2D) (None, 1, 1, 1152) 56448 ['block6c_se_reduce[0][0]']
block6c_se_excite (Multiply) (None, 1, 1, 1152) 0 ['block6c_activation[0][0]',
'block6c_se_expand[0][0]']
block6c_project_conv (Conv2D) (None, 1, 1, 192) 221184 ['block6c_se_excite[0][0]']
block6c_project_bn (BatchNorma (None, 1, 1, 192) 768 ['block6c_project_conv[0][0]']
lization)
block6c_drop (Dropout) (None, 1, 1, 192) 0 ['block6c_project_bn[0][0]']
block6c_add (Add) (None, 1, 1, 192) 0 ['block6c_drop[0][0]',
'block6b_add[0][0]']
block6d_expand_conv (Conv2D) (None, 1, 1, 1152) 221184 ['block6c_add[0][0]']
block6d_expand_bn (BatchNormal (None, 1, 1, 1152) 4608 ['block6d_expand_conv[0][0]']
ization)
block6d_expand_activation (Act (None, 1, 1, 1152) 0 ['block6d_expand_bn[0][0]']
ivation)
block6d_dwconv (DepthwiseConv2 (None, 1, 1, 1152) 28800 ['block6d_expand_activation[0][0]
D) ']
block6d_bn (BatchNormalization (None, 1, 1, 1152) 4608 ['block6d_dwconv[0][0]']
)
block6d_activation (Activation (None, 1, 1, 1152) 0 ['block6d_bn[0][0]']
)
block6d_se_squeeze (GlobalAver (None, 1152) 0 ['block6d_activation[0][0]']
agePooling2D)
block6d_se_reshape (Reshape) (None, 1, 1, 1152) 0 ['block6d_se_squeeze[0][0]']
block6d_se_reduce (Conv2D) (None, 1, 1, 48) 55344 ['block6d_se_reshape[0][0]']
block6d_se_expand (Conv2D) (None, 1, 1, 1152) 56448 ['block6d_se_reduce[0][0]']
block6d_se_excite (Multiply) (None, 1, 1, 1152) 0 ['block6d_activation[0][0]',
'block6d_se_expand[0][0]']
block6d_project_conv (Conv2D) (None, 1, 1, 192) 221184 ['block6d_se_excite[0][0]']
block6d_project_bn (BatchNorma (None, 1, 1, 192) 768 ['block6d_project_conv[0][0]']
lization)
block6d_drop (Dropout) (None, 1, 1, 192) 0 ['block6d_project_bn[0][0]']
block6d_add (Add) (None, 1, 1, 192) 0 ['block6d_drop[0][0]',
'block6c_add[0][0]']
block7a_expand_conv (Conv2D) (None, 1, 1, 1152) 221184 ['block6d_add[0][0]']
block7a_expand_bn (BatchNormal (None, 1, 1, 1152) 4608 ['block7a_expand_conv[0][0]']
ization)
block7a_expand_activation (Act (None, 1, 1, 1152) 0 ['block7a_expand_bn[0][0]']
ivation)
block7a_dwconv (DepthwiseConv2 (None, 1, 1, 1152) 10368 ['block7a_expand_activation[0][0]
D) ']
block7a_bn (BatchNormalization (None, 1, 1, 1152) 4608 ['block7a_dwconv[0][0]']
)
block7a_activation (Activation (None, 1, 1, 1152) 0 ['block7a_bn[0][0]']
)
block7a_se_squeeze (GlobalAver (None, 1152) 0 ['block7a_activation[0][0]']
agePooling2D)
block7a_se_reshape (Reshape) (None, 1, 1, 1152) 0 ['block7a_se_squeeze[0][0]']
block7a_se_reduce (Conv2D) (None, 1, 1, 48) 55344 ['block7a_se_reshape[0][0]']
block7a_se_expand (Conv2D) (None, 1, 1, 1152) 56448 ['block7a_se_reduce[0][0]']
block7a_se_excite (Multiply) (None, 1, 1, 1152) 0 ['block7a_activation[0][0]',
'block7a_se_expand[0][0]']
block7a_project_conv (Conv2D) (None, 1, 1, 320) 368640 ['block7a_se_excite[0][0]']
block7a_project_bn (BatchNorma (None, 1, 1, 320) 1280 ['block7a_project_conv[0][0]']
lization)
top_conv (Conv2D) (None, 1, 1, 1280) 409600 ['block7a_project_bn[0][0]']
top_bn (BatchNormalization) (None, 1, 1, 1280) 5120 ['top_conv[0][0]']
top_activation (Activation) (None, 1, 1, 1280) 0 ['top_bn[0][0]']
global_average_pooling2d_4 (Gl (None, 1280) 0 ['top_activation[0][0]']
obalAveragePooling2D)
dense_8 (Dense) (None, 512) 655872 ['global_average_pooling2d_4[0][0
]']
dropout_4 (Dropout) (None, 512) 0 ['dense_8[0][0]']
dense_9 (Dense) (None, 1) 513 ['dropout_4[0][0]']
==================================================================================================
Total params: 4,705,956
Trainable params: 4,663,933
Non-trainable params: 42,023
__________________________________________________________________________________________________
Epoch 1/12
1050/1050 [==============================] - 110s 63ms/step - loss: 0.7208 - accuracy: 0.6196 - val_loss: 1.4250 - val_accuracy: 0.4744 - lr: 0.0010
Epoch 2/12
1050/1050 [==============================] - 66s 62ms/step - loss: 0.6251 - accuracy: 0.6718 - val_loss: 0.9072 - val_accuracy: 0.5000 - lr: 0.0010
Epoch 3/12
1050/1050 [==============================] - 66s 63ms/step - loss: 0.6310 - accuracy: 0.6650 - val_loss: 0.7158 - val_accuracy: 0.5000 - lr: 0.0010
Epoch 4/12
1050/1050 [==============================] - ETA: 0s - loss: 0.6358 - accuracy: 0.6638
Epoch 4: ReduceLROnPlateau reducing learning rate to 0.0003000000142492354.
1050/1050 [==============================] - 67s 64ms/step - loss: 0.6358 - accuracy: 0.6638 - val_loss: 0.7876 - val_accuracy: 0.5000 - lr: 0.0010
Epoch 5/12
1050/1050 [==============================] - 67s 63ms/step - loss: 0.6035 - accuracy: 0.6924 - val_loss: 0.6128 - val_accuracy: 0.6739 - lr: 3.0000e-04
Epoch 6/12
1050/1050 [==============================] - 67s 64ms/step - loss: 0.5947 - accuracy: 0.6955 - val_loss: 0.7092 - val_accuracy: 0.5000 - lr: 3.0000e-04
Epoch 7/12
1050/1050 [==============================] - ETA: 0s - loss: 0.5948 - accuracy: 0.6943
Epoch 7: ReduceLROnPlateau reducing learning rate to 9.000000427477062e-05.
1050/1050 [==============================] - 67s 64ms/step - loss: 0.5948 - accuracy: 0.6943 - val_loss: 0.6702 - val_accuracy: 0.6428 - lr: 3.0000e-04
Epoch 8/12
1050/1050 [==============================] - 67s 63ms/step - loss: 0.5931 - accuracy: 0.7001 - val_loss: 0.5902 - val_accuracy: 0.6939 - lr: 9.0000e-05
Epoch 9/12
1050/1050 [==============================] - 68s 64ms/step - loss: 0.5768 - accuracy: 0.7101 - val_loss: 0.5708 - val_accuracy: 0.6989 - lr: 9.0000e-05
Epoch 10/12
1050/1050 [==============================] - 74s 70ms/step - loss: 0.5684 - accuracy: 0.7179 - val_loss: 0.6469 - val_accuracy: 0.5650 - lr: 9.0000e-05
Epoch 11/12
1050/1050 [==============================] - ETA: 0s - loss: 0.5688 - accuracy: 0.7156
Epoch 11: ReduceLROnPlateau reducing learning rate to 2.700000040931627e-05.
1050/1050 [==============================] - 71s 67ms/step - loss: 0.5688 - accuracy: 0.7156 - val_loss: 1.0351 - val_accuracy: 0.5000 - lr: 9.0000e-05
Epoch 12/12
1050/1050 [==============================] - 68s 65ms/step - loss: 0.5579 - accuracy: 0.7289 - val_loss: 0.5634 - val_accuracy: 0.7256 - lr: 2.7000e-05
57/57 [==============================] - 2s 8ms/step
--------------------------------------------------------------------------------
Classification Matrix
--------------------------------------------------------------------------------
precision recall f1-score support
Normal (Class 0) 0.75 0.63 0.68 900
Pneumonia (Class 1) 0.68 0.79 0.73 900
accuracy 0.71 1800
macro avg 0.71 0.71 0.71 1800
weighted avg 0.71 0.71 0.71 1800
--------------------------------------------------------------------------------
<Figure size 640x480 with 0 Axes>
Observation:
In the series of experiments conducted to optimize pneumonia detection from chest X-ray images, several critical components were examined. The preprocessing stage standardized the image sizes and augmented the dataset, while five distinct pre-trained deep learning models, including ResNet50, ResNet101, MobileNet, EfficientNetB0, and VGG19, were rigorously tested. These models, loaded with pre-trained weights from ImageNet, were fine-tuned to enhance their performance.
The training strategy employed categorical cross-entropy loss and the Adam optimizer, supplemented with early stopping and learning rate reduction on a plateau to counter overfitting. Subsequently, an in-depth evaluation of these models revealed key performance metrics, including accuracy, AUC, precision, recall, and F1-score, shedding light on their effectiveness.
Among the various models assessed, MobileNet emerged as the frontrunner in the pursuit of accurate pneumonia detection. With an impressive accuracy rate of 73% and an AUC score of 77.56, MobileNet outperformed its counterparts. Its noteworthy attribute was the equilibrium it struck between precision and recall for both normal and pneumonia cases, rendering it particularly suitable for real-world deployment.
EfficientNetB0 also displayed competitive performance with accuracy rate of 71% and an AUC score of 74.11, closely following MobileNet with commendable precision and recall metrics. These models excelled in the crucial task of distinguishing between normal and pneumonia cases, signifying their potential as valuable tools in medical diagnosis. Ultimately, while the other models offered valuable insights, MobileNet's robust and balanced performance made it the standout choice for pneumonia detection from chest X-ray images.
Limitations of Transfer Learning
While transfer learning offers many advantages in training deep neural networks for image classification tasks, it also comes with certain limitations and considerations that should be acknowledged:
Transfer learning assumes that the source domain (pre-trained model's domain) and the target domain (Healthcare Domain) have some degree of similarity. If the domains are significantly different, the pre-trained model's features may not be relevant, leading to suboptimal performance. For example, if the source domain is natural images, and the target domain is medical images, domain mismatch issues may arise.
Fine-Tuning Challenges Fine-tuning a pre-trained model requires selecting appropriate layers to train, freezing others, and choosing suitable learning rates. If not done correctly, it can lead to overfitting or underfitting. Fine-tuning can be a time-consuming and resource-intensive process, requiring careful experimentation.
Lack of Explainability Transfer learning models, especially deep neural networks with numerous layers, can be challenging to interpret and explain. This lack of transparency can be a limitation, particularly in medical applications where understanding the model's decisions is crucial.
Data Quantity and Quality The success of transfer learning often depends on having a sufficient amount of high-quality data. In some cases, medical datasets may be limited, leading to potential issues with model generalization. Augmenting the dataset and ensuring data quality are essential steps to mitigate this limitation.
Task-Specific Features Pre-trained models are designed for general-purpose tasks such as object recognition or image classification. They may not capture task-specific features or nuances in the target domain. Fine-tuning can help adapt the model, but there may still be limitations in capturing domain-specific knowledge.
Ethical Considerations When using pre-trained models for medical diagnosis or other critical applications, ethical considerations come into play. The model's performance, biases, and potential consequences of false positives or false negatives must be carefully evaluated and monitored.
Computational Resources Training and fine-tuning deep learning models, especially large ones like those in the report, require significant computational resources. Deploying such models in resource-constrained environments may not always be feasible.
Model Updates Pre-trained models may become outdated as new architectures and techniques emerge. Regularly updating and retraining models to incorporate the latest advancements is essential to maintain high performance.
Understanding these limitations and carefully considering them during the model development process is crucial for making informed decisions when applying transfer learning to specific tasks, particularly in critical domains like healthcare. It's essential to strike a balance between leveraging pre-trained knowledge and tailoring models to suit the unique requirements of the target domain.
What is RCNN?
Region-based Convolutional Neural Network was developed by Ross Girshick. It is an Object Detection Algorithm which is region based. This family of machine learning models is mostly used in computer vision, especially for object detection where multiple objects are involved.
Difference between CNN and RCNN
Convolutional Neural Network (CNN) is primarily used for image classification, whereas RCNN is used for object detection. CNN can only give us information regarding the class of the objects, and the location of the object being classified is not identified. CNN also does not perform well when there are multiple different objects in the visual field due to interference.
On the other hand, when it comes to RCNN, object localization is the primary problem that needs to be solved for object detection. Object detection helps identify types or classes of objects whose presence is located. The brute force approach also called exhaustive search uses a sliding window of different sizes to locate the objects in the image.
R-CNN uses a combination of both segmentation and exhaustive search which is called selective search. The input image is segmented into different regions and the different shapes are separated by using different colors.
An iterative greedy algorithm approach repeatedly combines smaller regions with larger regions. The selective search proposes candidate object locations from region proposals. Features for these proposals were computed by feeding them into CNN architecture. A class-specific linear SVM model is used to classify each region.
Architecture of RCNN
The images given as input are run through the search algorithm to extract region proposals. The regions that are warped are fed into CNN architecture and finally, the regions are classified using support vectors.
Each class is independently trained by a binary SVM model. It takes the generated feature vectors and produces a confidence score as to whether the object is present in that particular region. As an extra step, a bounding box regressor is used to localize the objects which are present in the image more precisely.
The regressor is a scale-invariant linear regression model which precisely locates the bounding box in the image. This method sometimes results in extra bounding boxes which are handled by using a non-maximum suppression algorithm.
The algorithm discards objects whose confidence score falls below a set threshold value. Regions with the highest probability and don’t have an intersection over union with the predicted regions are selected.
# Declarations
IMAGE_SIZE = 224
# Initialise the learning rate, epochs and batch size
RCNN_EPOCH = 5
batch_size = 8
IMAGE_PATH = '/kaggle/input/pneumonia-dataset/stage_2_train_images/stage_2_train_images/'
data = []
labels = []
Region of interest Extractor for positive and negative classes
# Prepare Training data
train_df = pd.read_csv('/kaggle/input/pneumonia-dataset/stage_2_train_labels.csv')
train_df.fillna(0,inplace=True)
# Functions to extract the bounding boxes and preprocess the image
def roiExtractor(row,patientId):
dicom_data = pydicom.read_file(os.path.join(IMAGE_PATH + '%s.dcm' % patientId))
img = dicom_data.pixel_array
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# Get the bounding box elements
bb = [int(row['x']),int(row['y']),int(row['x']) + int(row['width']),int(row['y']) + int(row['height'])]
# Crop the image
roi = img[bb[1]:bb[3], bb[0]:bb[2]]
# Reshape the image
roi = cv2.resize(roi,(IMAGE_SIZE,IMAGE_SIZE),interpolation=cv2.INTER_CUBIC)
# Convert the image to an array
roi = img_to_array(roi)
# Preprocess the image
roi = preprocess_input(roi)
return roi
pos_count = 0
neg_count = 0
# Looping through the excel sheet rows
for idx, row in train_df.iterrows():
if (row['Target'] == 1) :
if (pos_count <= 1000):
roi = roiExtractor(row,row['patientId'])
# Append the data and labels for the positive class
data.append(roi)
labels.append(int(1))
pos_count += 1
elif (neg_count <= 1000):
dicom_data = pydicom.read_file(os.path.join(IMAGE_PATH + '%s.dcm' % row['patientId']))
img = dicom_data.pixel_array
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# Extract patches
patches = extract_patches_2d(img,(128,128),max_patches=1)
# For each patch do the augmentation
for patch in patches:
# Reshape the image
roi = cv2.resize(patch,(IMAGE_SIZE,IMAGE_SIZE),interpolation=cv2.INTER_CUBIC)
# Convert the image to an array
roi = img_to_array(roi)
# Preprocess the image
roi = preprocess_input(roi)
# Append the data into the data folder and labels folder
neg_count += 1
data.append(roi)
labels.append(int(0))
#print('--'*40); print('Saving the feature engineered dataframe for future use'); print('--'*40)
#save_pickle(data, 'Milestone2_images_data.pkl')
Train and Test Data Preparation
#data = open_pickle('Milestone2_images_data.pkl')
# convert the data and labels to NumPy arrays
data = np.array(data, dtype="float32")
labels = np.array(labels)
print(data.shape)
print(labels.shape)
# perform one-hot encoding on the labels
lb = LabelBinarizer()
# Fit transform the labels array
labels = lb.fit_transform(labels)
# Convert this to categorical
labels = to_categorical(labels)
# Partition data to train and test set with 85 : 15 split
(trainX, testX, trainY, testY) = train_test_split(data, labels,test_size=0.15, stratify=labels, random_state=42)
print("training data shape :",trainX.shape)
print("testing data shape :",testX.shape)
print("training labels shape :",trainY.shape)
print("testing labels shape :",testY.shape)
# Create a image generator with data augmentation
aug = ImageDataGenerator(
rotation_range=40,
zoom_range=0.25,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.30,
horizontal_flip=True,
fill_mode="nearest")
# Converting the target names as string for classification report
target_names = list(map(str,lb.classes_))
(2002, 224, 224, 3) (2002,) training data shape : (1701, 224, 224, 3) testing data shape : (301, 224, 224, 3) training labels shape : (1701, 2) testing labels shape : (301, 2)
Training a Resnet50 model using transfer learning
def create_model_9() :
model = ResNet50(weights="imagenet")
x = model.output
x = Flatten(name="flatten")(x)
x = Dense(128, activation="relu")(x)
x = Dropout(0.5)(x)
predictions = Dense(2, activation="softmax")(x)
model = Model(model.input, predictions)
model.summary()
model.compile(loss="binary_crossentropy", optimizer='adam', metrics=["accuracy"])
return model
Model Prediction for pneumonia detection
model_9 = create_model_9()
history_9 = model_9.fit(aug.flow(trainX, trainY, batch_size=32),steps_per_epoch=len(trainX) // 32,validation_data=(testX, testY),
validation_steps=len(testX) //32,epochs=20)
Model: "model_1"
__________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
==================================================================================================
input_2 (InputLayer) [(None, 224, 224, 3 0 []
)]
conv1_pad (ZeroPadding2D) (None, 230, 230, 3) 0 ['input_2[0][0]']
conv1_conv (Conv2D) (None, 112, 112, 64 9472 ['conv1_pad[0][0]']
)
conv1_bn (BatchNormalization) (None, 112, 112, 64 256 ['conv1_conv[0][0]']
)
conv1_relu (Activation) (None, 112, 112, 64 0 ['conv1_bn[0][0]']
)
pool1_pad (ZeroPadding2D) (None, 114, 114, 64 0 ['conv1_relu[0][0]']
)
pool1_pool (MaxPooling2D) (None, 56, 56, 64) 0 ['pool1_pad[0][0]']
conv2_block1_1_conv (Conv2D) (None, 56, 56, 64) 4160 ['pool1_pool[0][0]']
conv2_block1_1_bn (BatchNormal (None, 56, 56, 64) 256 ['conv2_block1_1_conv[0][0]']
ization)
conv2_block1_1_relu (Activatio (None, 56, 56, 64) 0 ['conv2_block1_1_bn[0][0]']
n)
conv2_block1_2_conv (Conv2D) (None, 56, 56, 64) 36928 ['conv2_block1_1_relu[0][0]']
conv2_block1_2_bn (BatchNormal (None, 56, 56, 64) 256 ['conv2_block1_2_conv[0][0]']
ization)
conv2_block1_2_relu (Activatio (None, 56, 56, 64) 0 ['conv2_block1_2_bn[0][0]']
n)
conv2_block1_0_conv (Conv2D) (None, 56, 56, 256) 16640 ['pool1_pool[0][0]']
conv2_block1_3_conv (Conv2D) (None, 56, 56, 256) 16640 ['conv2_block1_2_relu[0][0]']
conv2_block1_0_bn (BatchNormal (None, 56, 56, 256) 1024 ['conv2_block1_0_conv[0][0]']
ization)
conv2_block1_3_bn (BatchNormal (None, 56, 56, 256) 1024 ['conv2_block1_3_conv[0][0]']
ization)
conv2_block1_add (Add) (None, 56, 56, 256) 0 ['conv2_block1_0_bn[0][0]',
'conv2_block1_3_bn[0][0]']
conv2_block1_out (Activation) (None, 56, 56, 256) 0 ['conv2_block1_add[0][0]']
conv2_block2_1_conv (Conv2D) (None, 56, 56, 64) 16448 ['conv2_block1_out[0][0]']
conv2_block2_1_bn (BatchNormal (None, 56, 56, 64) 256 ['conv2_block2_1_conv[0][0]']
ization)
conv2_block2_1_relu (Activatio (None, 56, 56, 64) 0 ['conv2_block2_1_bn[0][0]']
n)
conv2_block2_2_conv (Conv2D) (None, 56, 56, 64) 36928 ['conv2_block2_1_relu[0][0]']
conv2_block2_2_bn (BatchNormal (None, 56, 56, 64) 256 ['conv2_block2_2_conv[0][0]']
ization)
conv2_block2_2_relu (Activatio (None, 56, 56, 64) 0 ['conv2_block2_2_bn[0][0]']
n)
conv2_block2_3_conv (Conv2D) (None, 56, 56, 256) 16640 ['conv2_block2_2_relu[0][0]']
conv2_block2_3_bn (BatchNormal (None, 56, 56, 256) 1024 ['conv2_block2_3_conv[0][0]']
ization)
conv2_block2_add (Add) (None, 56, 56, 256) 0 ['conv2_block1_out[0][0]',
'conv2_block2_3_bn[0][0]']
conv2_block2_out (Activation) (None, 56, 56, 256) 0 ['conv2_block2_add[0][0]']
conv2_block3_1_conv (Conv2D) (None, 56, 56, 64) 16448 ['conv2_block2_out[0][0]']
conv2_block3_1_bn (BatchNormal (None, 56, 56, 64) 256 ['conv2_block3_1_conv[0][0]']
ization)
conv2_block3_1_relu (Activatio (None, 56, 56, 64) 0 ['conv2_block3_1_bn[0][0]']
n)
conv2_block3_2_conv (Conv2D) (None, 56, 56, 64) 36928 ['conv2_block3_1_relu[0][0]']
conv2_block3_2_bn (BatchNormal (None, 56, 56, 64) 256 ['conv2_block3_2_conv[0][0]']
ization)
conv2_block3_2_relu (Activatio (None, 56, 56, 64) 0 ['conv2_block3_2_bn[0][0]']
n)
conv2_block3_3_conv (Conv2D) (None, 56, 56, 256) 16640 ['conv2_block3_2_relu[0][0]']
conv2_block3_3_bn (BatchNormal (None, 56, 56, 256) 1024 ['conv2_block3_3_conv[0][0]']
ization)
conv2_block3_add (Add) (None, 56, 56, 256) 0 ['conv2_block2_out[0][0]',
'conv2_block3_3_bn[0][0]']
conv2_block3_out (Activation) (None, 56, 56, 256) 0 ['conv2_block3_add[0][0]']
conv3_block1_1_conv (Conv2D) (None, 28, 28, 128) 32896 ['conv2_block3_out[0][0]']
conv3_block1_1_bn (BatchNormal (None, 28, 28, 128) 512 ['conv3_block1_1_conv[0][0]']
ization)
conv3_block1_1_relu (Activatio (None, 28, 28, 128) 0 ['conv3_block1_1_bn[0][0]']
n)
conv3_block1_2_conv (Conv2D) (None, 28, 28, 128) 147584 ['conv3_block1_1_relu[0][0]']
conv3_block1_2_bn (BatchNormal (None, 28, 28, 128) 512 ['conv3_block1_2_conv[0][0]']
ization)
conv3_block1_2_relu (Activatio (None, 28, 28, 128) 0 ['conv3_block1_2_bn[0][0]']
n)
conv3_block1_0_conv (Conv2D) (None, 28, 28, 512) 131584 ['conv2_block3_out[0][0]']
conv3_block1_3_conv (Conv2D) (None, 28, 28, 512) 66048 ['conv3_block1_2_relu[0][0]']
conv3_block1_0_bn (BatchNormal (None, 28, 28, 512) 2048 ['conv3_block1_0_conv[0][0]']
ization)
conv3_block1_3_bn (BatchNormal (None, 28, 28, 512) 2048 ['conv3_block1_3_conv[0][0]']
ization)
conv3_block1_add (Add) (None, 28, 28, 512) 0 ['conv3_block1_0_bn[0][0]',
'conv3_block1_3_bn[0][0]']
conv3_block1_out (Activation) (None, 28, 28, 512) 0 ['conv3_block1_add[0][0]']
conv3_block2_1_conv (Conv2D) (None, 28, 28, 128) 65664 ['conv3_block1_out[0][0]']
conv3_block2_1_bn (BatchNormal (None, 28, 28, 128) 512 ['conv3_block2_1_conv[0][0]']
ization)
conv3_block2_1_relu (Activatio (None, 28, 28, 128) 0 ['conv3_block2_1_bn[0][0]']
n)
conv3_block2_2_conv (Conv2D) (None, 28, 28, 128) 147584 ['conv3_block2_1_relu[0][0]']
conv3_block2_2_bn (BatchNormal (None, 28, 28, 128) 512 ['conv3_block2_2_conv[0][0]']
ization)
conv3_block2_2_relu (Activatio (None, 28, 28, 128) 0 ['conv3_block2_2_bn[0][0]']
n)
conv3_block2_3_conv (Conv2D) (None, 28, 28, 512) 66048 ['conv3_block2_2_relu[0][0]']
conv3_block2_3_bn (BatchNormal (None, 28, 28, 512) 2048 ['conv3_block2_3_conv[0][0]']
ization)
conv3_block2_add (Add) (None, 28, 28, 512) 0 ['conv3_block1_out[0][0]',
'conv3_block2_3_bn[0][0]']
conv3_block2_out (Activation) (None, 28, 28, 512) 0 ['conv3_block2_add[0][0]']
conv3_block3_1_conv (Conv2D) (None, 28, 28, 128) 65664 ['conv3_block2_out[0][0]']
conv3_block3_1_bn (BatchNormal (None, 28, 28, 128) 512 ['conv3_block3_1_conv[0][0]']
ization)
conv3_block3_1_relu (Activatio (None, 28, 28, 128) 0 ['conv3_block3_1_bn[0][0]']
n)
conv3_block3_2_conv (Conv2D) (None, 28, 28, 128) 147584 ['conv3_block3_1_relu[0][0]']
conv3_block3_2_bn (BatchNormal (None, 28, 28, 128) 512 ['conv3_block3_2_conv[0][0]']
ization)
conv3_block3_2_relu (Activatio (None, 28, 28, 128) 0 ['conv3_block3_2_bn[0][0]']
n)
conv3_block3_3_conv (Conv2D) (None, 28, 28, 512) 66048 ['conv3_block3_2_relu[0][0]']
conv3_block3_3_bn (BatchNormal (None, 28, 28, 512) 2048 ['conv3_block3_3_conv[0][0]']
ization)
conv3_block3_add (Add) (None, 28, 28, 512) 0 ['conv3_block2_out[0][0]',
'conv3_block3_3_bn[0][0]']
conv3_block3_out (Activation) (None, 28, 28, 512) 0 ['conv3_block3_add[0][0]']
conv3_block4_1_conv (Conv2D) (None, 28, 28, 128) 65664 ['conv3_block3_out[0][0]']
conv3_block4_1_bn (BatchNormal (None, 28, 28, 128) 512 ['conv3_block4_1_conv[0][0]']
ization)
conv3_block4_1_relu (Activatio (None, 28, 28, 128) 0 ['conv3_block4_1_bn[0][0]']
n)
conv3_block4_2_conv (Conv2D) (None, 28, 28, 128) 147584 ['conv3_block4_1_relu[0][0]']
conv3_block4_2_bn (BatchNormal (None, 28, 28, 128) 512 ['conv3_block4_2_conv[0][0]']
ization)
conv3_block4_2_relu (Activatio (None, 28, 28, 128) 0 ['conv3_block4_2_bn[0][0]']
n)
conv3_block4_3_conv (Conv2D) (None, 28, 28, 512) 66048 ['conv3_block4_2_relu[0][0]']
conv3_block4_3_bn (BatchNormal (None, 28, 28, 512) 2048 ['conv3_block4_3_conv[0][0]']
ization)
conv3_block4_add (Add) (None, 28, 28, 512) 0 ['conv3_block3_out[0][0]',
'conv3_block4_3_bn[0][0]']
conv3_block4_out (Activation) (None, 28, 28, 512) 0 ['conv3_block4_add[0][0]']
conv4_block1_1_conv (Conv2D) (None, 14, 14, 256) 131328 ['conv3_block4_out[0][0]']
conv4_block1_1_bn (BatchNormal (None, 14, 14, 256) 1024 ['conv4_block1_1_conv[0][0]']
ization)
conv4_block1_1_relu (Activatio (None, 14, 14, 256) 0 ['conv4_block1_1_bn[0][0]']
n)
conv4_block1_2_conv (Conv2D) (None, 14, 14, 256) 590080 ['conv4_block1_1_relu[0][0]']
conv4_block1_2_bn (BatchNormal (None, 14, 14, 256) 1024 ['conv4_block1_2_conv[0][0]']
ization)
conv4_block1_2_relu (Activatio (None, 14, 14, 256) 0 ['conv4_block1_2_bn[0][0]']
n)
conv4_block1_0_conv (Conv2D) (None, 14, 14, 1024 525312 ['conv3_block4_out[0][0]']
)
conv4_block1_3_conv (Conv2D) (None, 14, 14, 1024 263168 ['conv4_block1_2_relu[0][0]']
)
conv4_block1_0_bn (BatchNormal (None, 14, 14, 1024 4096 ['conv4_block1_0_conv[0][0]']
ization) )
conv4_block1_3_bn (BatchNormal (None, 14, 14, 1024 4096 ['conv4_block1_3_conv[0][0]']
ization) )
conv4_block1_add (Add) (None, 14, 14, 1024 0 ['conv4_block1_0_bn[0][0]',
) 'conv4_block1_3_bn[0][0]']
conv4_block1_out (Activation) (None, 14, 14, 1024 0 ['conv4_block1_add[0][0]']
)
conv4_block2_1_conv (Conv2D) (None, 14, 14, 256) 262400 ['conv4_block1_out[0][0]']
conv4_block2_1_bn (BatchNormal (None, 14, 14, 256) 1024 ['conv4_block2_1_conv[0][0]']
ization)
conv4_block2_1_relu (Activatio (None, 14, 14, 256) 0 ['conv4_block2_1_bn[0][0]']
n)
conv4_block2_2_conv (Conv2D) (None, 14, 14, 256) 590080 ['conv4_block2_1_relu[0][0]']
conv4_block2_2_bn (BatchNormal (None, 14, 14, 256) 1024 ['conv4_block2_2_conv[0][0]']
ization)
conv4_block2_2_relu (Activatio (None, 14, 14, 256) 0 ['conv4_block2_2_bn[0][0]']
n)
conv4_block2_3_conv (Conv2D) (None, 14, 14, 1024 263168 ['conv4_block2_2_relu[0][0]']
)
conv4_block2_3_bn (BatchNormal (None, 14, 14, 1024 4096 ['conv4_block2_3_conv[0][0]']
ization) )
conv4_block2_add (Add) (None, 14, 14, 1024 0 ['conv4_block1_out[0][0]',
) 'conv4_block2_3_bn[0][0]']
conv4_block2_out (Activation) (None, 14, 14, 1024 0 ['conv4_block2_add[0][0]']
)
conv4_block3_1_conv (Conv2D) (None, 14, 14, 256) 262400 ['conv4_block2_out[0][0]']
conv4_block3_1_bn (BatchNormal (None, 14, 14, 256) 1024 ['conv4_block3_1_conv[0][0]']
ization)
conv4_block3_1_relu (Activatio (None, 14, 14, 256) 0 ['conv4_block3_1_bn[0][0]']
n)
conv4_block3_2_conv (Conv2D) (None, 14, 14, 256) 590080 ['conv4_block3_1_relu[0][0]']
conv4_block3_2_bn (BatchNormal (None, 14, 14, 256) 1024 ['conv4_block3_2_conv[0][0]']
ization)
conv4_block3_2_relu (Activatio (None, 14, 14, 256) 0 ['conv4_block3_2_bn[0][0]']
n)
conv4_block3_3_conv (Conv2D) (None, 14, 14, 1024 263168 ['conv4_block3_2_relu[0][0]']
)
conv4_block3_3_bn (BatchNormal (None, 14, 14, 1024 4096 ['conv4_block3_3_conv[0][0]']
ization) )
conv4_block3_add (Add) (None, 14, 14, 1024 0 ['conv4_block2_out[0][0]',
) 'conv4_block3_3_bn[0][0]']
conv4_block3_out (Activation) (None, 14, 14, 1024 0 ['conv4_block3_add[0][0]']
)
conv4_block4_1_conv (Conv2D) (None, 14, 14, 256) 262400 ['conv4_block3_out[0][0]']
conv4_block4_1_bn (BatchNormal (None, 14, 14, 256) 1024 ['conv4_block4_1_conv[0][0]']
ization)
conv4_block4_1_relu (Activatio (None, 14, 14, 256) 0 ['conv4_block4_1_bn[0][0]']
n)
conv4_block4_2_conv (Conv2D) (None, 14, 14, 256) 590080 ['conv4_block4_1_relu[0][0]']
conv4_block4_2_bn (BatchNormal (None, 14, 14, 256) 1024 ['conv4_block4_2_conv[0][0]']
ization)
conv4_block4_2_relu (Activatio (None, 14, 14, 256) 0 ['conv4_block4_2_bn[0][0]']
n)
conv4_block4_3_conv (Conv2D) (None, 14, 14, 1024 263168 ['conv4_block4_2_relu[0][0]']
)
conv4_block4_3_bn (BatchNormal (None, 14, 14, 1024 4096 ['conv4_block4_3_conv[0][0]']
ization) )
conv4_block4_add (Add) (None, 14, 14, 1024 0 ['conv4_block3_out[0][0]',
) 'conv4_block4_3_bn[0][0]']
conv4_block4_out (Activation) (None, 14, 14, 1024 0 ['conv4_block4_add[0][0]']
)
conv4_block5_1_conv (Conv2D) (None, 14, 14, 256) 262400 ['conv4_block4_out[0][0]']
conv4_block5_1_bn (BatchNormal (None, 14, 14, 256) 1024 ['conv4_block5_1_conv[0][0]']
ization)
conv4_block5_1_relu (Activatio (None, 14, 14, 256) 0 ['conv4_block5_1_bn[0][0]']
n)
conv4_block5_2_conv (Conv2D) (None, 14, 14, 256) 590080 ['conv4_block5_1_relu[0][0]']
conv4_block5_2_bn (BatchNormal (None, 14, 14, 256) 1024 ['conv4_block5_2_conv[0][0]']
ization)
conv4_block5_2_relu (Activatio (None, 14, 14, 256) 0 ['conv4_block5_2_bn[0][0]']
n)
conv4_block5_3_conv (Conv2D) (None, 14, 14, 1024 263168 ['conv4_block5_2_relu[0][0]']
)
conv4_block5_3_bn (BatchNormal (None, 14, 14, 1024 4096 ['conv4_block5_3_conv[0][0]']
ization) )
conv4_block5_add (Add) (None, 14, 14, 1024 0 ['conv4_block4_out[0][0]',
) 'conv4_block5_3_bn[0][0]']
conv4_block5_out (Activation) (None, 14, 14, 1024 0 ['conv4_block5_add[0][0]']
)
conv4_block6_1_conv (Conv2D) (None, 14, 14, 256) 262400 ['conv4_block5_out[0][0]']
conv4_block6_1_bn (BatchNormal (None, 14, 14, 256) 1024 ['conv4_block6_1_conv[0][0]']
ization)
conv4_block6_1_relu (Activatio (None, 14, 14, 256) 0 ['conv4_block6_1_bn[0][0]']
n)
conv4_block6_2_conv (Conv2D) (None, 14, 14, 256) 590080 ['conv4_block6_1_relu[0][0]']
conv4_block6_2_bn (BatchNormal (None, 14, 14, 256) 1024 ['conv4_block6_2_conv[0][0]']
ization)
conv4_block6_2_relu (Activatio (None, 14, 14, 256) 0 ['conv4_block6_2_bn[0][0]']
n)
conv4_block6_3_conv (Conv2D) (None, 14, 14, 1024 263168 ['conv4_block6_2_relu[0][0]']
)
conv4_block6_3_bn (BatchNormal (None, 14, 14, 1024 4096 ['conv4_block6_3_conv[0][0]']
ization) )
conv4_block6_add (Add) (None, 14, 14, 1024 0 ['conv4_block5_out[0][0]',
) 'conv4_block6_3_bn[0][0]']
conv4_block6_out (Activation) (None, 14, 14, 1024 0 ['conv4_block6_add[0][0]']
)
conv5_block1_1_conv (Conv2D) (None, 7, 7, 512) 524800 ['conv4_block6_out[0][0]']
conv5_block1_1_bn (BatchNormal (None, 7, 7, 512) 2048 ['conv5_block1_1_conv[0][0]']
ization)
conv5_block1_1_relu (Activatio (None, 7, 7, 512) 0 ['conv5_block1_1_bn[0][0]']
n)
conv5_block1_2_conv (Conv2D) (None, 7, 7, 512) 2359808 ['conv5_block1_1_relu[0][0]']
conv5_block1_2_bn (BatchNormal (None, 7, 7, 512) 2048 ['conv5_block1_2_conv[0][0]']
ization)
conv5_block1_2_relu (Activatio (None, 7, 7, 512) 0 ['conv5_block1_2_bn[0][0]']
n)
conv5_block1_0_conv (Conv2D) (None, 7, 7, 2048) 2099200 ['conv4_block6_out[0][0]']
conv5_block1_3_conv (Conv2D) (None, 7, 7, 2048) 1050624 ['conv5_block1_2_relu[0][0]']
conv5_block1_0_bn (BatchNormal (None, 7, 7, 2048) 8192 ['conv5_block1_0_conv[0][0]']
ization)
conv5_block1_3_bn (BatchNormal (None, 7, 7, 2048) 8192 ['conv5_block1_3_conv[0][0]']
ization)
conv5_block1_add (Add) (None, 7, 7, 2048) 0 ['conv5_block1_0_bn[0][0]',
'conv5_block1_3_bn[0][0]']
conv5_block1_out (Activation) (None, 7, 7, 2048) 0 ['conv5_block1_add[0][0]']
conv5_block2_1_conv (Conv2D) (None, 7, 7, 512) 1049088 ['conv5_block1_out[0][0]']
conv5_block2_1_bn (BatchNormal (None, 7, 7, 512) 2048 ['conv5_block2_1_conv[0][0]']
ization)
conv5_block2_1_relu (Activatio (None, 7, 7, 512) 0 ['conv5_block2_1_bn[0][0]']
n)
conv5_block2_2_conv (Conv2D) (None, 7, 7, 512) 2359808 ['conv5_block2_1_relu[0][0]']
conv5_block2_2_bn (BatchNormal (None, 7, 7, 512) 2048 ['conv5_block2_2_conv[0][0]']
ization)
conv5_block2_2_relu (Activatio (None, 7, 7, 512) 0 ['conv5_block2_2_bn[0][0]']
n)
conv5_block2_3_conv (Conv2D) (None, 7, 7, 2048) 1050624 ['conv5_block2_2_relu[0][0]']
conv5_block2_3_bn (BatchNormal (None, 7, 7, 2048) 8192 ['conv5_block2_3_conv[0][0]']
ization)
conv5_block2_add (Add) (None, 7, 7, 2048) 0 ['conv5_block1_out[0][0]',
'conv5_block2_3_bn[0][0]']
conv5_block2_out (Activation) (None, 7, 7, 2048) 0 ['conv5_block2_add[0][0]']
conv5_block3_1_conv (Conv2D) (None, 7, 7, 512) 1049088 ['conv5_block2_out[0][0]']
conv5_block3_1_bn (BatchNormal (None, 7, 7, 512) 2048 ['conv5_block3_1_conv[0][0]']
ization)
conv5_block3_1_relu (Activatio (None, 7, 7, 512) 0 ['conv5_block3_1_bn[0][0]']
n)
conv5_block3_2_conv (Conv2D) (None, 7, 7, 512) 2359808 ['conv5_block3_1_relu[0][0]']
conv5_block3_2_bn (BatchNormal (None, 7, 7, 512) 2048 ['conv5_block3_2_conv[0][0]']
ization)
conv5_block3_2_relu (Activatio (None, 7, 7, 512) 0 ['conv5_block3_2_bn[0][0]']
n)
conv5_block3_3_conv (Conv2D) (None, 7, 7, 2048) 1050624 ['conv5_block3_2_relu[0][0]']
conv5_block3_3_bn (BatchNormal (None, 7, 7, 2048) 8192 ['conv5_block3_3_conv[0][0]']
ization)
conv5_block3_add (Add) (None, 7, 7, 2048) 0 ['conv5_block2_out[0][0]',
'conv5_block3_3_bn[0][0]']
conv5_block3_out (Activation) (None, 7, 7, 2048) 0 ['conv5_block3_add[0][0]']
avg_pool (GlobalAveragePooling (None, 2048) 0 ['conv5_block3_out[0][0]']
2D)
predictions (Dense) (None, 1000) 2049000 ['avg_pool[0][0]']
flatten (Flatten) (None, 1000) 0 ['predictions[0][0]']
dense_2 (Dense) (None, 128) 128128 ['flatten[0][0]']
dropout_1 (Dropout) (None, 128) 0 ['dense_2[0][0]']
dense_3 (Dense) (None, 2) 258 ['dropout_1[0][0]']
==================================================================================================
Total params: 25,765,098
Trainable params: 25,711,978
Non-trainable params: 53,120
__________________________________________________________________________________________________
Epoch 1/20
53/53 [==============================] - 60s 425ms/step - loss: 0.6505 - accuracy: 0.7406 - val_loss: 0.7056 - val_accuracy: 0.4983
Epoch 2/20
53/53 [==============================] - 21s 402ms/step - loss: 0.6037 - accuracy: 0.7058 - val_loss: 0.7087 - val_accuracy: 0.4983
Epoch 3/20
53/53 [==============================] - 21s 389ms/step - loss: 0.5682 - accuracy: 0.6872 - val_loss: 0.6941 - val_accuracy: 0.5515
Epoch 4/20
53/53 [==============================] - 21s 402ms/step - loss: 0.5636 - accuracy: 0.7124 - val_loss: 0.8896 - val_accuracy: 0.4983
Epoch 5/20
53/53 [==============================] - 21s 399ms/step - loss: 0.5020 - accuracy: 0.7633 - val_loss: 0.7580 - val_accuracy: 0.5083
Epoch 6/20
53/53 [==============================] - 21s 392ms/step - loss: 0.5396 - accuracy: 0.7322 - val_loss: 0.7110 - val_accuracy: 0.4884
Epoch 7/20
53/53 [==============================] - 21s 400ms/step - loss: 0.4802 - accuracy: 0.7819 - val_loss: 1.1416 - val_accuracy: 0.5017
Epoch 8/20
53/53 [==============================] - 21s 401ms/step - loss: 0.4356 - accuracy: 0.8125 - val_loss: 0.6848 - val_accuracy: 0.4850
Epoch 9/20
53/53 [==============================] - 22s 406ms/step - loss: 0.4469 - accuracy: 0.7927 - val_loss: 0.8004 - val_accuracy: 0.4983
Epoch 10/20
53/53 [==============================] - 21s 399ms/step - loss: 0.4173 - accuracy: 0.8167 - val_loss: 0.7992 - val_accuracy: 0.4983
Epoch 11/20
53/53 [==============================] - 22s 407ms/step - loss: 0.4578 - accuracy: 0.7983 - val_loss: 1.1477 - val_accuracy: 0.4983
Epoch 12/20
53/53 [==============================] - 21s 385ms/step - loss: 0.3892 - accuracy: 0.8256 - val_loss: 1.0411 - val_accuracy: 0.5349
Epoch 13/20
53/53 [==============================] - 21s 398ms/step - loss: 0.3868 - accuracy: 0.8280 - val_loss: 0.6298 - val_accuracy: 0.6910
Epoch 14/20
53/53 [==============================] - 21s 391ms/step - loss: 0.3989 - accuracy: 0.8346 - val_loss: 0.9432 - val_accuracy: 0.5781
Epoch 15/20
53/53 [==============================] - 21s 399ms/step - loss: 0.4010 - accuracy: 0.8214 - val_loss: 1.1858 - val_accuracy: 0.4485
Epoch 16/20
53/53 [==============================] - 21s 396ms/step - loss: 0.3563 - accuracy: 0.8616 - val_loss: 1.3935 - val_accuracy: 0.5814
Epoch 17/20
53/53 [==============================] - 21s 393ms/step - loss: 0.3653 - accuracy: 0.8430 - val_loss: 1.1004 - val_accuracy: 0.6113
Epoch 18/20
53/53 [==============================] - 21s 404ms/step - loss: 0.3568 - accuracy: 0.8478 - val_loss: 0.7895 - val_accuracy: 0.5714
Epoch 19/20
53/53 [==============================] - 21s 394ms/step - loss: 0.3304 - accuracy: 0.8628 - val_loss: 0.8945 - val_accuracy: 0.6412
Epoch 20/20
53/53 [==============================] - 21s 400ms/step - loss: 0.3971 - accuracy: 0.8304 - val_loss: 1.2770 - val_accuracy: 0.6346
def maxOverlap(boxes):
'''
boxes : This is the cordinates of the boxes which have the object
returns : A list of boxes which do not have much overlap
'''
# Convert the bounding boxes into an array
boxes = np.array(boxes)
# Initialise a box to pick the ids of the selected boxes and include the largest box
selected = []
# Continue the loop till the number of ids remaining in the box is greater than 1
while len(boxes) > 1:
# First calculate the area of the bounding boxes
x1 = boxes[:, 0]
y1 = boxes[:, 1]
x2 = boxes[:, 2]
y2 = boxes[:, 3]
area = (x2 - x1) * (y2 - y1)
# Sort the bounding boxes based on its area
ids = np.argsort(area)
#print('ids',ids)
# Take the coordinates of the box with the largest area
lx1 = boxes[ids[-1], 0]
ly1 = boxes[ids[-1], 1]
lx2 = boxes[ids[-1], 2]
ly2 = boxes[ids[-1], 3]
# Include the largest box into the selected list
selected.append(boxes[ids[-1]].tolist())
# Initialise a list for getting those ids that needs to be removed.
remove = []
remove.append(ids[-1])
# We loop through each of the other boxes and find the overlap of the boxes with the largest box
for id in ids[:-1]:
#print('id',id)
# The maximum of the starting x cordinate is where the overlap along width starts
ox1 = np.maximum(lx1, boxes[id,0])
# The maximum of the starting y cordinate is where the overlap along height starts
oy1 = np.maximum(ly1, boxes[id,1])
# The minimum of the ending x cordinate is where the overlap along width ends
ox2 = np.minimum(lx2, boxes[id,2])
# The minimum of the ending y cordinate is where the overlap along height ends
oy2 = np.minimum(ly2, boxes[id,3])
# Find area of the overlapping coordinates
oa = (ox2 - ox1) * (oy2 - oy1)
# Find the ratio of overlapping area of the smaller box with respect to its original area
olRatio = oa/area[id]
# If the overlap is greater than threshold include the id in the remove list
if olRatio > 0.40:
remove.append(id)
# Remove those ids from the original boxes
boxes = np.delete(boxes, remove,axis = 0)
# Break the while loop if nothing to remove
if len(remove) == 0:
break
# Append the remaining boxes to the selected
for i in range(len(boxes)):
selected.append(boxes[i].tolist())
return np.array(selected)
# Function to show an image with actual bounding box coordinates
def show_image_with_bboxes(patientId):
# Create a plot
f, ax = plt.subplots(figsize=(5, 5))
ID = "Actual: ",format(patientId)
orig_image = pydicom.read_file(os.path.join(IMAGE_PATH + '%s.dcm' % patientId))
image = orig_image.pixel_array
plt.imshow(cv2.cvtColor(orig_image.pixel_array, cv2.COLOR_BGR2RGB))
plt.title(ID)
# Copy all the rows where the patientId matches
filter = train_df[train_df['patientId'] == patientId]
# Collect data from all entries for a given patientId
for j, filtered_row in enumerate(list(filter.T.to_dict().values())):
x, y, width, height = filtered_row['x'], filtered_row['y'], filtered_row['width'], filtered_row['height']
rectangle = Rectangle(xy=(x,y),width=width, height=height, color="red",alpha = 0.2)
ax.add_patch(rectangle)
# make predictions on the test set
def predict_model(model, history, patientId):
predictions = model.predict(testX, batch_size=32)
# For each prediction we need to find the index with maximum probability
predIdxs = np.argmax(predictions, axis=1)
# Print the classification report
print(classification_report(testY.argmax(axis=1), predIdxs,target_names=target_names ,zero_division=0))
# plot the training loss and accuracy
N = 20
plt.style.use("ggplot")
plt.figure()
plt.plot(np.arange(0, N), history.history["loss"], label="train_loss")
plt.plot(np.arange(0, N), history.history["accuracy"], label="train_acc")
plt.title("Training Loss and Accuracy")
plt.xlabel("Epoch #")
plt.ylabel("Loss/Accuracy")
plt.legend(loc="lower left")
plt.savefig("plot.png")
plt.show()
# Implementing selective search to generate bounding box proposals
dicom_data = pydicom.read_file(os.path.join(IMAGE_PATH + '%s.dcm' % patientId))
img = dicom_data.pixel_array
img = cv2.resize(img, (224, 224))
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
ss = cv2.ximgproc.segmentation.createSelectiveSearchSegmentation()
ss.setBaseImage(img)
#ss.switchToSelectiveSearchFast()
ss.switchToSelectiveSearchQuality()
rects = ss.process()
# Initialise lists to store the region of interest from the image and its bounding boxes
proposals = []
boxes = []
max_proposals = 100
# Iterate over the bounding box coordinates to extract region of interest from image
for (x, y, w, h) in rects[:max_proposals]:
# if the width or height of the region is more than 40% of the
# image width or height, ignore it (i.e., filter out large
# objects that are likely false-positives)
if w / 224 > 0.2 or h / 224 > 0.2:
continue
# Crop region of interest from the image
roi = img[y:y + h, x:x + w]
# Convert to RGB format as CV2 has output in BGR format
roi = cv2.cvtColor(roi, cv2.COLOR_BGR2RGB)
# Resize image to our standar size
roi = cv2.resize(roi, (224,224), interpolation=cv2.INTER_CUBIC)
# Preprocess the image
roi = img_to_array(roi)
roi = preprocess_input(roi)
# Update the proposal and bounding boxes
proposals.append(roi)
boxes.append((x, y, x + w, y + h))
# Convert proposals and bouding boxes to NumPy arrays
proposals = np.array(proposals, dtype="float32")
boxes = np.array(boxes, dtype="int32")
# Classify the proposals based on the fine tuned model
proba = model.predict(proposals)
# Find the predicted labels
labels = lb.classes_[np.argmax(proba, axis=1)]
# Get the ids where the predictions are 'pneumonia'
idxs = np.where(labels == 1)[0]
# Using the indexes, extract the bounding boxes and prediction probabilities of 'pneumonia' class
boxes = boxes[idxs]
proba = proba[idxs][:, 1]
# Filter the bounding boxes using a prediction probability threshold
pred_threshold = 0.995
# Select only those ids where the probability is greater than the threshold
idxs = np.where(proba >= pred_threshold)
boxes = boxes[idxs]
proba = proba[idxs]
# Clone the original image for visualisation and inserting text
clone = img.copy()
# Iterate through the bounding boxes and associated probabilities
for (box, prob) in zip(boxes, proba):
# Draw the bounding box, label, and probability on the image
(startX, startY, endX, endY) = box
cv2.rectangle(clone, (startX, startY), (endX, endY),(0, 255, 0), 2)
# Initialising the cordinate for writing the text
y = startY - 10 if startY - 10 > 10 else startY + 10
# Getting the text to be attached on top of the box
text= "Pneumonia: {:.2f}%".format(prob * 100)
# Visualise the text on the image
cv2.putText(clone, text, (startX, y),cv2.FONT_HERSHEY_SIMPLEX, 0.25, (0, 255, 0), 1)
# Visualise the bounding boxes on the image
plt.imshow(clone,aspect='equal')
plt.show()
# Applying non maxima suppression
selected = maxOverlap(boxes)
clone = img.copy()
plt.imshow(img,aspect='equal')
for (startX, startY, endX, endY) in selected:
cv2.rectangle(clone, (startX, startY), (endX, endY), (0, 255, 0), 2)
plt.imshow(clone,aspect='equal')
plt.title("Predicted Image")
plt.show()
# SHow the actual image for comparision
# Function to show an image with actual bounding box coordinates
show_image_with_bboxes(patientId)
patientId = '76f71a93-8105-4c79-a010-0cfa86f0061a'
predict_model(model_9, history_9, patientId)
10/10 [==============================] - 1s 56ms/step
precision recall f1-score support
0 0.79 0.36 0.50 150
1 0.59 0.91 0.71 151
accuracy 0.63 301
macro avg 0.69 0.63 0.60 301
weighted avg 0.69 0.63 0.60 301
2/2 [==============================] - 0s 48ms/step
Observation
• Preprocessed the positive and negative classes of images and then built our train and test sets
• Fine tuned the Resnet50 model to cater to our use case and made it our classifier.
• Built the inference pipeline using the fine tuned classifier
• Applied non maxima suppression to get the bounding boxes over the pneumonia region.
• Overall 69% Average accuracy is achieved with this model.
• The precision to identify positive Pneumonia cases is less (59%).
• Model has higher recall (91%) and higher F1 score (71%) for class 1.
• Selective search algorithm has its own disadvantages. Since this is a very basic model and many new improved versions of RCNN are available, it is better to try out those models for Object detection.
Advantages and Applications of RCNN
Object localization and object detection are the two core operations in computer vision and therefore have a lot of real-world applications in a variety of fields. It is used in autonomous vehicles for perceiving objects in their surroundings to ensure a safe driving experience. In the field of construction, RCNN can be used for maintenance work like analyzing high-resolution pictures of rust In the manufacturing industry, RCNN can be used for defective product identification and automated inspections. Generally, since the base model of RCNN does not have the performance needed for real-time application, models built on this base such as Fast-RCNN, Faster RCNN, or mask RCNN are used. All these variations try to improvise the testing and the analysis of the generated region proposals.
Disadvantages of RCNN
The selective search algorithm is very rigid. Since it’s a fixed algorithm no learning happens during the search. This sometimes could result in the generation of bad region proposals. It is very time-consuming since the number of region proposals is approximately 2000 or more. Multiple steps in the RCNN architecture have to be trained separately. Hence the implementation of the model is very slow. Real-time application is not possible due to the amount of time it takes to test images. Feature maps of the region proposals need to be saved. This increases the amount of memory space needed during training.
Regional Convolutional Neural Network is an object detection algorithm hence it is quite different from image classification. This led to more efficient models built on top of the base RCNN model which improves efficiency and speed. It helped deal with a lot of problems CNN faced in terms of multi-objects and finding the location of the objects in the image. It led to a lot of variations built on top of this technology and is one of the core technology used in emerging fields like computer vision.
What is Faster-RCNN? Faster R-CNN is an object detection algorithm proposed by Shaoqing Ren, Kaiming He, Ross Girshick, and Jian Sun in 2015. Faster R-CNN is an object detection model that improves on Fast R-CNN by utilising a region proposal network (RPN) with the CNN model. The RPN shares full-image convolutional features with the detection network, enabling region proposals. It is a fully convolutional network that simultaneously predicts object bounds and objectness scores at each position.
The RPN is trained end-to-end to generate high-quality region proposals, which are used by Fast R-CNN for detection. RPN and Fast R-CNN are merged into a single network by sharing their convolutional features: the RPN component tells the unified network where to look.
Faster R-CNN consists of two modules. The first module is a deep fully convolutional network that proposes regions, and the second module is the Fast R-CNN detector that uses the proposed regions.
Defining the adjusted image size to 224 to help train the model faster and accordingly defined FACTOR variable to resize the bounding box data from train set
Used 3 different approaches with varying image size to train the model.
1) Original image size with single channel - predicted results were good however it was taking long to train.
2) Resized actual image to 128 X 128 X 3 - took less training time however prediction was less accurate.
3) Current Optimal Approach: Resized actual image to 224 X 224 X 3 - In this case, the training time has reduced significantly and prediction results have also improved.
Train and Test Data Preparation
Loading the “stage_2_train_labels.csv” file into pandas dataframe
• patientId – which refers to the patientId’s corresponding image name
• x - upper-left x coordinate of the bounding box
• y - upper-left y coordinate of the bounding box
• width – the width of the bounding box
• height – the height of the bounding box
• Target – binary target indicating if this image has evidence of pneumonia
There is a total of 30,227 entries, no missing values with 9,555 images have bounding boxes.
In our solution, as we use Faster R-CNN object detector with PyTorch
# Read the CSV file
train_df = pd.read_csv('/kaggle/input/pneumonia-dataset/stage_2_train_labels.csv')
IMAGE_PATH = '/kaggle/input/pneumonia-dataset/stage_2_train_images/stage_2_train_images/'
IMAGE_SIZE = 1024 #sample_pixel_array.shape[0]
ADJUSTED_IMAGE_SIZE=224
FACTOR = ADJUSTED_IMAGE_SIZE/IMAGE_SIZE
train_df.fillna(0,inplace=True)
train_df['x'] = train_df['x'].astype('int');
train_df['y'] = train_df['y'].astype('int');
train_df['width'] = train_df['width'].astype('int');
train_df['height'] = train_df['height'].astype('int');
print('Original dataframe shape:', train_df.shape)
train_labels_df_pos = pd.DataFrame(columns=['patientId', 'x', 'y', 'width', 'height'])
k = 0
for i in range(len(train_df)):
if train_df.iloc[i]['Target'] == 1:
train_labels_df_pos.loc[k] = train_df.loc[i]
k += 1
print('Positive instances dataframe shape:', train_labels_df_pos.shape)
#train_paths = [os.path.join(IMAGE_PATH, image[0]) for image in train_labels_df_pos.values]
Original dataframe shape: (30227, 6) Positive instances dataframe shape: (9555, 5)
train_labels_df_pos['x'] = train_labels_df_pos['x'].astype('int');
train_labels_df_pos['y'] = train_labels_df_pos['y'].astype('int');
train_labels_df_pos['width'] = train_labels_df_pos['width'].astype('int');
train_labels_df_pos['height'] = train_labels_df_pos['height'].astype('int');
Using PyTorch Dataset and DataLoader
In PyTorch, it’s considered a best practice to create a class that inherits from PyTorch’s Dataset class to load the data. This will give us more control over the data and helps keep the code modular.
In class PneumoniaDataset, we’ve defined a function called get_item that loads the images, labelled classes, and bounding box coordinates which are then converted to PyTorch’s Tensor object. The images are reshaped to a fixed size (224 X224 X 3).
We further use the PyTorch DataLoader for the dataset instance to took care of batching, shuffling, and sampling of the train and valid dataset.
We will use the pre-trained model included with torchvision.
• Downloading the Faster R-CNN Resnet50 FPN V2 model with pretrained weights on 167M images.
• We set the desired num_classes as ‘2’
class PneumoniaDataset(Dataset):
def __init__(self, dataframe, image_dir, transforms=None):
super().__init__()
self.image_ids = dataframe['patientId'].unique()
self.df = dataframe
self.image_dir = image_dir
self.transforms = transforms
def __getitem__(self, index):
# load images and bounding boxes
image_id = self.image_ids[index]
records = self.df[self.df['patientId'] == image_id]
dicom_data = pydicom.read_file(os.path.join(self.image_dir + '%s.dcm' % image_id))
img = dicom_data.pixel_array
img = cv2.resize(img, (ADJUSTED_IMAGE_SIZE, ADJUSTED_IMAGE_SIZE))
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB).astype(np.float32)
img /= 255.0
boxes = records[['x', 'y', 'width', 'height']].values
boxes[:, 2] = boxes[:, 0] + boxes[:, 2]
boxes[:, 3] = boxes[:, 1] + boxes[:, 3]
#Resizing
boxes[:, 0]=boxes[:, 0].astype(np.int32)* FACTOR
boxes[:, 1]=boxes[:, 1].astype(np.int32)* FACTOR
boxes[:, 2]=boxes[:, 2].astype(np.int32)* FACTOR
boxes[:, 3]=boxes[:, 3].astype(np.int32)* FACTOR
boxes=np.vstack(boxes).astype(np.float32)
#print("Final co:")
#print(boxes[:,0],boxes[:,2],boxes[:,1],boxes[:,3])
area = (boxes[:, 3] - boxes[:, 1]) * (boxes[:, 2] - boxes[:, 0])
area = np.vstack(area).astype(np.float32)
area = torch.as_tensor(area, dtype=torch.float32)
# there is only one class
labels = torch.ones((records.shape[0],), dtype=torch.int64)
# suppose all instances are not crowd
iscrowd = torch.zeros((records.shape[0],), dtype=torch.int64)
target = {}
target['boxes'] = boxes
target['labels'] = labels
target['patientId'] = torch.tensor([index])
target['area'] = area
target['iscrowd'] = iscrowd
if self.transforms:
sample = {
'image': img,
'bboxes': target['boxes'],
'labels': labels
}
sample = self.transforms(**sample)
img = sample['image']
target['boxes'] = torch.stack(tuple(map(torch.FloatTensor, zip(*sample['bboxes'])))).permute(1, 0)
return img, target
def __len__(self):
return self.image_ids.shape[0]
# Albumentations
def get_train_transform():
return A.Compose([
A.Resize(width=ADJUSTED_IMAGE_SIZE,height=ADJUSTED_IMAGE_SIZE),
A.Flip(0.5),
A.RandomRotate90(0.5),
A.MotionBlur(p=0.2),
A.MedianBlur(blur_limit=3, p=0.1),
A.Blur(blur_limit=3, p=0.1),
ToTensorV2(p=1.0)
], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})
def get_valid_transform():
return A.Compose([
A.Resize(width=ADJUSTED_IMAGE_SIZE,height=ADJUSTED_IMAGE_SIZE),
ToTensorV2(p=1.0)
], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})
def collate_fn(batch):
return tuple(zip(*batch))
class Averager:
def __init__(self):
self.current_total = 0.0
self.iterations = 0.0
def send(self, value):
self.current_total += value
self.iterations += 1
@property
def value(self):
if self.iterations == 0:
return 0
else:
return 1.0 * self.current_total / self.iterations
def reset(self):
self.current_total = 0.0
self.iterations = 0.0
image_ids = train_labels_df_pos['patientId'].unique()
valid_ids = image_ids[-300:]
train_ids = image_ids[:-300]
print(f"Training instance: {len(train_ids)}")
print(f"Validation instances: {len(valid_ids)}")
valid_df = train_labels_df_pos[train_labels_df_pos['patientId'].isin(valid_ids)]
train_df = train_labels_df_pos[train_labels_df_pos['patientId'].isin(train_ids)]
print('Train dataframe shape:', train_df.shape)
print('Valid dataframe shape:', valid_df.shape)
train_dataset = PneumoniaDataset(train_df, IMAGE_PATH, get_train_transform())
valid_dataset = PneumoniaDataset(valid_df, IMAGE_PATH, get_valid_transform())
print('train_dataset and valid_dataset are loaded :)')
print("We have: {} training examples and {} validation examples".format(len(train_dataset), len(valid_dataset)))
train_data_loader = DataLoader(train_dataset, batch_size=8, shuffle=False, num_workers=2, collate_fn=collate_fn)
valid_data_loader = DataLoader(valid_dataset, batch_size=8, shuffle=False, num_workers=2, collate_fn=collate_fn)
Training instance: 5712 Validation instances: 300 Train dataframe shape: (9057, 5) Valid dataframe shape: (498, 5) train_dataset and valid_dataset are loaded :) We have: 5712 training examples and 300 validation examples
def calculate_image_precision(gts, preds, thresholds = (0.5, ), form = 'coco') -> float:
# https://www.kaggle.com/sadmanaraf/wheat-detection-using-faster-rcnn-train
"""Calculates image precision.
Args:
gts: (List[List[Union[int, float]]]) Coordinates of the available ground-truth boxes
preds: (List[List[Union[int, float]]]) Coordinates of the predicted boxes,
sorted by confidence value (descending)
thresholds: (float) Different thresholds
form: (str) Format of the coordinates
Return:
(float) Precision
"""
n_threshold = len(thresholds)
image_precision = 0.0
ious = np.ones((len(gts), len(preds))) * -1
# ious = None
for threshold in thresholds:
precision_at_threshold = calculate_precision(gts.copy(), preds, threshold=threshold,
form=form, ious=ious)
image_precision += precision_at_threshold / n_threshold
return image_precision
def calculate_iou(gt, pr, form='pascal_voc') -> float:
# https://www.kaggle.com/sadmanaraf/wheat-detection-using-faster-rcnn-train
"""Calculates the Intersection over Union.
Args:
gt: (np.ndarray[Union[int, float]]) coordinates of the ground-truth box
pr: (np.ndarray[Union[int, float]]) coordinates of the prdected box
form: (str) gt/pred coordinates format
- pascal_voc: [xmin, ymin, xmax, ymax]
- coco: [xmin, ymin, w, h]
Returns:
(float) Intersection over union (0.0 <= iou <= 1.0)
"""
if form == 'coco':
gt = gt.copy()
pr = pr.copy()
gt[2] = gt[0] + gt[2]
gt[3] = gt[1] + gt[3]
pr[2] = pr[0] + pr[2]
pr[3] = pr[1] + pr[3]
# Calculate overlap area
dx = min(gt[2], pr[2]) - max(gt[0], pr[0]) + 1
if dx < 0:
return 0.0
dy = min(gt[3], pr[3]) - max(gt[1], pr[1]) + 1
if dy < 0:
return 0.0
overlap_area = dx * dy
# Calculate union area
union_area = (
(gt[2] - gt[0] + 1) * (gt[3] - gt[1] + 1) +
(pr[2] - pr[0] + 1) * (pr[3] - pr[1] + 1) -
overlap_area
)
return overlap_area / union_area
def find_best_match(gts, pred, pred_idx, threshold = 0.5, form = 'pascal_voc', ious=None) -> int:
# https://www.kaggle.com/sadmanaraf/wheat-detection-using-faster-rcnn-train
"""Returns the index of the 'best match' between the
ground-truth boxes and the prediction. The 'best match'
is the highest IoU. (0.0 IoUs are ignored).
Args:
gts: (List[List[Union[int, float]]]) Coordinates of the available ground-truth boxes
pred: (List[Union[int, float]]) Coordinates of the predicted box
pred_idx: (int) Index of the current predicted box
threshold: (float) Threshold
form: (str) Format of the coordinates
ious: (np.ndarray) len(gts) x len(preds) matrix for storing calculated ious.
Return:
(int) Index of the best match GT box (-1 if no match above threshold)
"""
best_match_iou = -np.inf
best_match_idx = -1
for gt_idx in range(len(gts)):
if gts[gt_idx][0] < 0:
# Already matched GT-box
continue
iou = -1 if ious is None else ious[gt_idx][pred_idx]
if iou < 0:
iou = calculate_iou(gts[gt_idx], pred, form=form)
if ious is not None:
ious[gt_idx][pred_idx] = iou
if iou < threshold:
continue
if iou > best_match_iou:
best_match_iou = iou
best_match_idx = gt_idx
return best_match_idx
def calculate_precision(gts, preds, threshold = 0.5, form = 'coco', ious=None) -> float:
# https://www.kaggle.com/sadmanaraf/wheat-detection-using-faster-rcnn-train
"""Calculates precision for GT - prediction pairs at one threshold.
Args:
gts: (List[List[Union[int, float]]]) Coordinates of the available ground-truth boxes
preds: (List[List[Union[int, float]]]) Coordinates of the predicted boxes,
sorted by confidence value (descending)
threshold: (float) Threshold
form: (str) Format of the coordinates
ious: (np.ndarray) len(gts) x len(preds) matrix for storing calculated ious.
Return:
(float) Precision
"""
n = len(preds)
tp = 0
fp = 0
for pred_idx in range(n):
best_match_gt_idx = find_best_match(gts, preds[pred_idx], pred_idx,
threshold=threshold, form=form, ious=ious)
if best_match_gt_idx >= 0:
# True positive: The predicted box matches a gt box with an IoU above the threshold.
tp += 1
# Remove the matched GT box
gts[best_match_gt_idx] = -1
else:
# No match
# False positive: indicates a predicted box had no associated gt box.
fp += 1
# False negative: indicates a gt box had no associated predicted box.
fn = (gts.sum(axis=1) > 0).sum()
return tp / (tp + fp + fn)
def train(dataloader, lr_scheduler, model, optimizer,
device, epoch, loss_hist, itr):
model.train()
start = time.time()
loss_hist.reset()
for images, targets in dataloader:
images = list(image.to(device) for image in images)
targets = [{k: v.to(device) for k, v in t.items()} for t in targets]
loss_dict = model(images, targets)
losses = sum(loss for loss in loss_dict.values())
loss_value = losses.item()
loss_hist.send(loss_value)
optimizer.zero_grad()
losses.backward()
optimizer.step()
if itr % 100 == 0:
print(f"Epoch #{epoch} iteration #{itr} loss: {loss_value}")
itr += 1
end = time.time()
return loss_hist, end, start
def validate(dataloader, model, device, iou_thresholds):
valid_image_precision = []
model.eval()
with torch.no_grad():
for images, targets in dataloader:
images = list(image.to(device) for image in images)
targets = [{k: v.to(device) for k, v in t.items()} for t in targets]
outputs = model(images)
for i, image in enumerate(images):
boxes = outputs[i]['boxes'].data.cpu().numpy()
scores = outputs[i]['scores'].data.cpu().numpy()
gt_boxes = targets[i]['boxes'].cpu().numpy()
preds_sorted_idx = np.argsort(scores)[::-1]
preds_sorted = boxes[preds_sorted_idx]
image_precision = calculate_image_precision(preds_sorted,
gt_boxes,
thresholds=iou_thresholds,
form='coco')
valid_image_precision.append(image_precision)
valid_prec = np.mean(valid_image_precision)
return valid_prec
Model Training and Validation
Now that the model has been initiated, we will train it. The parameter for setting the number of epochs for training is (num_epochs) and is set to 8. We have optimized the model using the SGD or Stochastic gradient descent method.
To minimize the loss function, we have set parameters as mentioned below -
• lr_scheduler is set to None
• Learning rate (lr) is set to 0.001
• requires_grad is set to True for gradients to be computed in back propagation
• momentum is set to 0.9 and weight_decay is set to 0.0005
If we want to save the trained weights, we can use torch.save to save and use the code underneath it to load it when needed.
For training, model is minimizing loss function.
For validation, our model is using Mean Average Precision and IOU threshold as 0.5
torch.cuda.is_available()
device = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')
def get_model():
# load the COCO pre-trained model
model = torchvision.models.detection.fasterrcnn_resnet50_fpn_v2(weights='DEFAULT')
# one class is pneumonia, and the other is background
num_classes = 2
# get the input features for the classifier
in_features = model.roi_heads.box_predictor.cls_score.in_features
# replace pre-trained head with our features head
# the head layer will classify the images based on our data input features
model.roi_heads.box_predictor = FastRCNNPredictor(in_features, num_classes)
return model
# learning parameters
num_epochs = 8
lr = 0.001
batch_size = 6
train_loss = []
precision = []
# initialize the Averager
loss_hist = Averager()
iou_thresholds = [x for x in np.arange(0.5, 0.76, 0.05)]
model = get_model().to(device)
params = [p for p in model.parameters() if p.requires_grad]
optimizer = torch.optim.SGD(params, lr=lr, momentum=0.9, weight_decay=0.0005)
lr_scheduler = None
for epoch in range(num_epochs):
itr = 1
train_loss_hist, end, start = train(train_data_loader, lr_scheduler,
model, optimizer, device,
epoch, loss_hist, itr)
valid_prec = validate(valid_data_loader, model, device, iou_thresholds)
print(f"Took {(end-start)/60:.3f} minutes for epoch# {epoch} to train")
print(f"Epoch #{epoch} Train loss: {train_loss_hist.value}")
print(f"Epoch #{epoch} Validation Precision: {valid_prec}")
train_loss.append(train_loss_hist.value)
precision.append(valid_prec)
# update the learning rate
if lr_scheduler is not None:
lr_scheduler.step()
torch.save(model.state_dict(), 'fasterrcnn_resnet50_fpn_pneumonia_detection.pth')
Downloading: "https://download.pytorch.org/models/fasterrcnn_resnet50_fpn_v2_coco-dd69338a.pth" to /root/.cache/torch/hub/checkpoints/fasterrcnn_resnet50_fpn_v2_coco-dd69338a.pth 100%|██████████| 167M/167M [00:01<00:00, 169MB/s]
Epoch #0 iteration #100 loss: 0.36503443121910095 Epoch #0 iteration #200 loss: 0.3593102693557739 Epoch #0 iteration #300 loss: 0.2480885237455368 Epoch #0 iteration #400 loss: 0.2986085116863251 Epoch #0 iteration #500 loss: 0.3035193085670471 Epoch #0 iteration #600 loss: 0.28615203499794006 Epoch #0 iteration #700 loss: 0.3310244083404541 Took 13.236 minutes for epoch# 0 to train Epoch #0 Train loss: 0.31745783341865913 Epoch #0 Validation Precision: 0.16418650793650794 Epoch #1 iteration #100 loss: 0.3212285339832306 Epoch #1 iteration #200 loss: 0.2446032613515854 Epoch #1 iteration #300 loss: 0.2512800991535187 Epoch #1 iteration #400 loss: 0.2469700276851654 Epoch #1 iteration #500 loss: 0.280222088098526 Epoch #1 iteration #600 loss: 0.2569520175457001 Epoch #1 iteration #700 loss: 0.28918418288230896 Took 13.172 minutes for epoch# 1 to train Epoch #1 Train loss: 0.2907198983706346 Epoch #1 Validation Precision: 0.18124236874236874 Epoch #2 iteration #100 loss: 0.3107304573059082 Epoch #2 iteration #200 loss: 0.25228461623191833 Epoch #2 iteration #300 loss: 0.23900437355041504 Epoch #2 iteration #400 loss: 0.2612660527229309 Epoch #2 iteration #500 loss: 0.25382906198501587 Epoch #2 iteration #600 loss: 0.29772183299064636 Epoch #2 iteration #700 loss: 0.2840990126132965 Took 13.180 minutes for epoch# 2 to train Epoch #2 Train loss: 0.2849202402123884 Epoch #2 Validation Precision: 0.21574675324675324 Epoch #3 iteration #100 loss: 0.28597262501716614 Epoch #3 iteration #200 loss: 0.22964544594287872 Epoch #3 iteration #300 loss: 0.2503037750720978 Epoch #3 iteration #400 loss: 0.22822438180446625 Epoch #3 iteration #500 loss: 0.25228601694107056 Epoch #3 iteration #600 loss: 0.2728104293346405 Epoch #3 iteration #700 loss: 0.27873876690864563 Took 13.213 minutes for epoch# 3 to train Epoch #3 Train loss: 0.28231633007943796 Epoch #3 Validation Precision: 0.20642436267436268 Epoch #4 iteration #100 loss: 0.3009676933288574 Epoch #4 iteration #200 loss: 0.24012809991836548 Epoch #4 iteration #300 loss: 0.2406945377588272 Epoch #4 iteration #400 loss: 0.23617839813232422 Epoch #4 iteration #500 loss: 0.25078845024108887 Epoch #4 iteration #600 loss: 0.2682115435600281 Epoch #4 iteration #700 loss: 0.28912079334259033 Took 13.188 minutes for epoch# 4 to train Epoch #4 Train loss: 0.2805629870971712 Epoch #4 Validation Precision: 0.175 Epoch #5 iteration #100 loss: 0.29064399003982544 Epoch #5 iteration #200 loss: 0.21240606904029846 Epoch #5 iteration #300 loss: 0.2539086639881134 Epoch #5 iteration #400 loss: 0.2431095540523529 Epoch #5 iteration #500 loss: 0.2606295943260193 Epoch #5 iteration #600 loss: 0.2684011459350586 Epoch #5 iteration #700 loss: 0.26061707735061646 Took 13.179 minutes for epoch# 5 to train Epoch #5 Train loss: 0.2790281881763488 Epoch #5 Validation Precision: 0.21448412698412697 Epoch #6 iteration #100 loss: 0.27606046199798584 Epoch #6 iteration #200 loss: 0.21379034221172333 Epoch #6 iteration #300 loss: 0.23880916833877563 Epoch #6 iteration #400 loss: 0.22491750121116638 Epoch #6 iteration #500 loss: 0.2669491469860077 Epoch #6 iteration #600 loss: 0.2712382376194 Epoch #6 iteration #700 loss: 0.2895532548427582 Took 13.181 minutes for epoch# 6 to train Epoch #6 Train loss: 0.27705336036551903 Epoch #6 Validation Precision: 0.251984126984127 Epoch #7 iteration #100 loss: 0.2856082022190094 Epoch #7 iteration #200 loss: 0.24783116579055786 Epoch #7 iteration #300 loss: 0.22515460848808289 Epoch #7 iteration #400 loss: 0.2147449254989624 Epoch #7 iteration #500 loss: 0.22745268046855927 Epoch #7 iteration #600 loss: 0.26497119665145874 Epoch #7 iteration #700 loss: 0.3005732595920563 Took 13.195 minutes for epoch# 7 to train Epoch #7 Train loss: 0.2743941983964597 Epoch #7 Validation Precision: 0.20499338624338623
Model Performance Evaluation
In our test dataset, we have 3000 images. We predicted bounding boxes and scores for the test images. Detection Threshold used is 0.8.
• Test images are obtained from the image path
• Each image is converted to image tensor using PyTorch’s Transforms
• The image is passed through the model to get the predictions
• Scores and box coordinates are obtained, but only prediction score > threshold is chosen.
Predicted result has XX images with one or more bounding boxes.
# plot the training loss
plt.figure()
plt.plot(train_loss, label='Training loss')
plt.legend()
plt.show()
# plot the validation precision
plt.figure()
plt.plot(precision, label='Validation precision')
plt.legend()
plt.show()
We load the saved dictionary state.
images_test_path = '/kaggle/input/pneumonia-dataset/stage_2_test_images/stage_2_test_images/'
test_images = os.listdir(images_test_path)
print(f"Validation instances: {len(test_images)}")
# # load a model; pre-trained on COCO
model = get_model()
# # os.makedirs('../validation_predictions', exist_ok=True)
model.load_state_dict(torch.load('fasterrcnn_resnet50_fpn_pneumonia_detection.pth'))
model.to(device)
Validation instances: 3000
FasterRCNN(
(transform): GeneralizedRCNNTransform(
Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
Resize(min_size=(800,), max_size=1333, mode='bilinear')
)
(backbone): BackboneWithFPN(
(body): IntermediateLayerGetter(
(conv1): Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)
(bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
(maxpool): MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)
(layer1): Sequential(
(0): Bottleneck(
(conv1): Conv2d(64, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
(downsample): Sequential(
(0): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(1): Bottleneck(
(conv1): Conv2d(256, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(2): Bottleneck(
(conv1): Conv2d(256, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
)
(layer2): Sequential(
(0): Bottleneck(
(conv1): Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
(downsample): Sequential(
(0): Conv2d(256, 512, kernel_size=(1, 1), stride=(2, 2), bias=False)
(1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(1): Bottleneck(
(conv1): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(2): Bottleneck(
(conv1): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(3): Bottleneck(
(conv1): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
)
(layer3): Sequential(
(0): Bottleneck(
(conv1): Conv2d(512, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
(downsample): Sequential(
(0): Conv2d(512, 1024, kernel_size=(1, 1), stride=(2, 2), bias=False)
(1): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(1): Bottleneck(
(conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(2): Bottleneck(
(conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(3): Bottleneck(
(conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(4): Bottleneck(
(conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(5): Bottleneck(
(conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
)
(layer4): Sequential(
(0): Bottleneck(
(conv1): Conv2d(1024, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
(downsample): Sequential(
(0): Conv2d(1024, 2048, kernel_size=(1, 1), stride=(2, 2), bias=False)
(1): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(1): Bottleneck(
(conv1): Conv2d(2048, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(2): Bottleneck(
(conv1): Conv2d(2048, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
)
)
(fpn): FeaturePyramidNetwork(
(inner_blocks): ModuleList(
(0): Conv2dNormActivation(
(0): Conv2d(256, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
(1): Conv2dNormActivation(
(0): Conv2d(512, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
(2): Conv2dNormActivation(
(0): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
(3): Conv2dNormActivation(
(0): Conv2d(2048, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(layer_blocks): ModuleList(
(0-3): 4 x Conv2dNormActivation(
(0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(extra_blocks): LastLevelMaxPool()
)
)
(rpn): RegionProposalNetwork(
(anchor_generator): AnchorGenerator()
(head): RPNHead(
(conv): Sequential(
(0): Conv2dNormActivation(
(0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(1): ReLU(inplace=True)
)
(1): Conv2dNormActivation(
(0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(1): ReLU(inplace=True)
)
)
(cls_logits): Conv2d(256, 3, kernel_size=(1, 1), stride=(1, 1))
(bbox_pred): Conv2d(256, 12, kernel_size=(1, 1), stride=(1, 1))
)
)
(roi_heads): RoIHeads(
(box_roi_pool): MultiScaleRoIAlign(featmap_names=['0', '1', '2', '3'], output_size=(7, 7), sampling_ratio=2)
(box_head): FastRCNNConvFCHead(
(0): Conv2dNormActivation(
(0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(2): ReLU(inplace=True)
)
(1): Conv2dNormActivation(
(0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(2): ReLU(inplace=True)
)
(2): Conv2dNormActivation(
(0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(2): ReLU(inplace=True)
)
(3): Conv2dNormActivation(
(0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(2): ReLU(inplace=True)
)
(4): Flatten(start_dim=1, end_dim=-1)
(5): Linear(in_features=12544, out_features=1024, bias=True)
(6): ReLU(inplace=True)
)
(box_predictor): FastRCNNPredictor(
(cls_score): Linear(in_features=1024, out_features=2, bias=True)
(bbox_pred): Linear(in_features=1024, out_features=8, bias=True)
)
)
)
For each image in the test dataset, we evaluate the model to obtain:
def format_prediction_string(boxes, scores):
pred_strings = []
for j in zip(scores, boxes):
pred_strings.append("{0:.4f} {1} {2} {3} {4}".format(j[0],
int(j[1][0]), int(j[1][1]),
int(j[1][2]), int(j[1][3])))
return " ".join(pred_strings)
Displaying sample images with predicted bounding box
detection_threshold = 0.8
results = []
model.eval()
f, axarr = plt.subplots(10, 3, figsize=(24,36))
axarr = axarr.ravel()
axidx = 0
with torch.no_grad():
for i, image in tqdm(enumerate(test_images), total=len(test_images)):
# plot image
ID = "ID: ",format(image)
#orig_image = cv2.imread(f"{images_test_path}/{test_images[i]}", cv2.IMREAD_COLOR)
orig_image = pydicom.read_file(os.path.join(images_test_path + '%s' % image))
image = orig_image.pixel_array
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB).astype(np.float32)
image /= 255.0
image = np.transpose(image, (2, 0, 1)).astype(np.float32)
image = torch.tensor(image, dtype=torch.float).cuda()
image = torch.unsqueeze(image, 0)
model.eval()
cpu_device = torch.device("cpu")
outputs = model(image)
outputs = [{k: v.to(cpu_device) for k, v in t.items()} for t in outputs]
if len(outputs[0]['boxes']) != 0:
for counter in range(len(outputs[0]['boxes'])):
boxes = outputs[0]['boxes'].data.cpu().numpy()
scores = outputs[0]['scores'].data.cpu().numpy()
boxes = boxes[scores >= detection_threshold].astype(np.int32)
draw_boxes = boxes.copy()
boxes[:, 2] = boxes[:, 2] - boxes[:, 0]
boxes[:, 3] = boxes[:, 3] - boxes[:, 1]
#print(image.shape)
#print(boxes)
draw_boxes = boxes.copy()
axarr[axidx].imshow(cv2.cvtColor(orig_image.pixel_array, cv2.COLOR_BGR2RGB))
axarr[axidx].set_title(ID)
for box in draw_boxes:
rectangle = Rectangle(xy= ((int(box[0]), int(box[1]))),width=int(box[2]),
height=int(box[3]), color="red",alpha = 0.1)
axarr[axidx].add_patch(rectangle)
axidx+=1
result = {
'patientId': test_images[i].split('.')[0],
'PredictionString': format_prediction_string(boxes, scores)
}
results.append(result)
else:
result = {
'patientId': test_images[i].split('.')[0],
'PredictionString': None
}
results.append(result)
i=i+1
#exit after 32 images
if i>29:
break
#sub_df = pd.DataFrame(results, columns=['patientId', 'PredictionString'])
#print(sub_df.head())
#sub_df.to_csv('submission.csv', index=False)
1%| | 29/3000 [00:04<07:53, 6.27it/s]
detection_threshold = 0.8
results = []
model.eval()
with torch.no_grad():
for i, image in tqdm(enumerate(test_images), total=len(test_images)):
# plot image
orig_image = pydicom.read_file(os.path.join(images_test_path + '%s' % image))
image = orig_image.pixel_array
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB).astype(np.float32)
image /= 255.0
image = np.transpose(image, (2, 0, 1)).astype(np.float32)
image = torch.tensor(image, dtype=torch.float).cuda()
image = torch.unsqueeze(image, 0)
model.eval()
cpu_device = torch.device("cpu")
outputs = model(image)
outputs = [{k: v.to(cpu_device) for k, v in t.items()} for t in outputs]
if len(outputs[0]['boxes']) != 0:
for counter in range(len(outputs[0]['boxes'])):
boxes = outputs[0]['boxes'].data.cpu().numpy()
scores = outputs[0]['scores'].data.cpu().numpy()
boxes = boxes[scores >= detection_threshold].astype(np.int32)
draw_boxes = boxes.copy()
boxes[:, 2] = boxes[:, 2] - boxes[:, 0]
boxes[:, 3] = boxes[:, 3] - boxes[:, 1]
draw_boxes = boxes.copy()
result = {
'patientId': test_images[i].split('.')[0],
'PredictionString': format_prediction_string(boxes, scores)
}
results.append(result)
else:
result = {
'patientId': test_images[i].split('.')[0],
'PredictionString': ''
}
results.append(result)
sub_df = pd.DataFrame(results, columns=['patientId', 'PredictionString'])
print(sub_df.head())
sub_df.to_csv('submission_frcnn.csv', index=False)
100%|██████████| 3000/3000 [06:00<00:00, 8.33it/s]
patientId \
0 12abc170-f1fe-45d3-b574-2f4d030e40cd
1 2abcf934-facd-40fc-a75e-0062441fd206
2 2da69f80-c59d-4e4a-b7e5-1d631ef4186b
3 13e4e6e6-faa2-4bbc-8e1e-610623de994e
4 2afe02a3-06da-42fa-b68f-3e9c921e5fb9
PredictionString
0
1 0.9593 561 275 173 436 0.9328 197 298 181 341
2 0.8360 235 456 146 139
3
4
Output:
sub_df
| patientId | PredictionString | |
|---|---|---|
| 0 | 12abc170-f1fe-45d3-b574-2f4d030e40cd | |
| 1 | 2abcf934-facd-40fc-a75e-0062441fd206 | 0.9593 561 275 173 436 0.9328 197 298 181 341 |
| 2 | 2da69f80-c59d-4e4a-b7e5-1d631ef4186b | 0.8360 235 456 146 139 |
| 3 | 13e4e6e6-faa2-4bbc-8e1e-610623de994e | |
| 4 | 2afe02a3-06da-42fa-b68f-3e9c921e5fb9 | |
| ... | ... | ... |
| 2995 | 1ef2bfbf-b68d-4981-8dc3-b5d7b54ad55e | |
| 2996 | 1fc3831a-7b78-48c5-90c1-af8971ee9eae | |
| 2997 | 20da1944-1714-4170-a08a-8b82c0788ad5 | 0.8825 200 502 197 113 |
| 2998 | 13c6a303-2c21-4edf-9dca-4999dafe8a4e | |
| 2999 | 2b83d54b-af50-4c15-9d53-d3b1c5381678 |
3000 rows × 2 columns
Prediction of bounding boxes with Confidence Score for the test images. Out of total of 3000 images, 1098 images have been detected as Pneumonia cases with one or more bounding boxes.
sub_df[sub_df['PredictionString']!='']
| patientId | PredictionString | |
|---|---|---|
| 1 | 2abcf934-facd-40fc-a75e-0062441fd206 | 0.9593 561 275 173 436 0.9328 197 298 181 341 |
| 2 | 2da69f80-c59d-4e4a-b7e5-1d631ef4186b | 0.8360 235 456 146 139 |
| 6 | 2a7df7aa-1314-40da-afc5-7af58ad1bee9 | 0.9230 142 344 211 421 |
| 8 | 0de33fbf-998c-4c91-9561-df7343873bc2 | 0.9313 646 533 184 193 |
| 9 | 1eeecd10-16a2-476f-8d81-867d5480bf01 | 0.9270 256 481 176 151 0.8682 637 438 173 228 |
| ... | ... | ... |
| 2985 | 140ebc5d-5a15-4948-b698-0a4b32d12a93 | 0.8276 144 359 228 491 |
| 2989 | 26586d01-b992-41c4-a7a4-c9f1f8d102ad | 0.9242 192 396 212 336 0.8151 625 434 189 383 |
| 2990 | 23ebfb85-2312-4a8b-8879-3cf48a1e8920 | 0.9041 646 367 200 382 |
| 2991 | 2dbac7d7-9100-4861-8e15-fa2adf82c6e3 | 0.8707 758 264 217 432 0.8068 285 252 240 408 |
| 2997 | 20da1944-1714-4170-a08a-8b82c0788ad5 | 0.8825 200 502 197 113 |
1098 rows × 2 columns
Function to show an image with predicted bounding box coordinates
validation_threshold=0.8
def show_pred_image_with_bboxes(patientId,axarr,axidx):
with torch.no_grad():
ID = "Predicted: ",format(patientId)
orig_image = pydicom.read_file(os.path.join(IMAGE_PATH + '%s.dcm' % patientId))
image = orig_image.pixel_array
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB).astype(np.float32)
image /= 255.0
image = np.transpose(image, (2, 0, 1)).astype(np.float32)
image = torch.tensor(image, dtype=torch.float).cuda()
image = torch.unsqueeze(image, 0)
model.eval()
cpu_device = torch.device("cpu")
outputs = model(image)
outputs = [{k: v.to(cpu_device) for k, v in t.items()} for t in outputs]
if len(outputs[0]['boxes']) != 0:
for counter in range(len(outputs[0]['boxes'])):
boxes = outputs[0]['boxes'].data.cpu().numpy()
scores = outputs[0]['scores'].data.cpu().numpy()
boxes = boxes[scores >= validation_threshold].astype(np.int32)
draw_boxes = boxes.copy()
boxes[:, 2] = boxes[:, 2] - boxes[:, 0]
boxes[:, 3] = boxes[:, 3] - boxes[:, 1]
draw_boxes = boxes.copy()
axarr[axidx].imshow(cv2.cvtColor(orig_image.pixel_array, cv2.COLOR_BGR2RGB))
axarr[axidx].set_title(ID)
for box in draw_boxes:
rectangle = Rectangle(xy= ((int(box[0]), int(box[1]))),width=int(box[2]),
height=int(box[3]), color="red",alpha = 0.1)
axarr[axidx].add_patch(rectangle)
Function to show an image with actual bounding box coordinates
def show_image_with_bboxes(patientId,axarr,axidx):
ID = "Actual: ",format(patientId)
id_= np.random.choice(train_labels_df_pos['patientId'].values)
orig_image = pydicom.read_file(os.path.join(IMAGE_PATH + '%s.dcm' % patientId))
image = orig_image.pixel_array
axarr[axidx].imshow(cv2.cvtColor(orig_image.pixel_array, cv2.COLOR_BGR2RGB))
axarr[axidx].set_title(ID)
boxes=train_labels_df_pos[['x','y','width','height']][train_labels_df_pos['patientId']==id_].values
for box in boxes:
x=box[0]
y=box[1]
w=box[2]
h=box[3]
axarr[axidx].add_patch(plt.Rectangle((x, y), w, h, color='red', fill=False, linewidth=3))
For Demonstration purposes, displaying sample images with actual and predicted bounding box.
#1352a7f3-1f0d-4f1f-af05-daa5d7f8624a
dataset = valid_df
f, axarr = plt.subplots(6, 2, figsize=(16,36))
axarr = axarr.ravel()
axidx = 0
image_id = valid_df.sample(6)['patientId'].reset_index(drop=True)
for i in range(6):
show_image_with_bboxes(image_id[i],axarr,axidx)
axidx+=1
show_pred_image_with_bboxes(image_id[i],axarr,axidx)
axidx+=1
Observation
With the backbone architecture as Resnet 50 VPN2, we are able to train/fit our data and provide results generating the bounding box coordinates of possibly infected chest area with high objectness scores of > 0.8 threshold. Training Loss is around 0.27 with 8 EPOCHS. This needs to be tried with more number of EPOCHS for better training and results. Out of 3000 test samples, 1098 samples have been detected as positive cases having one or more bounding boxes. The same results have been updated in the submission file.
Limitation of Faster R-CNN
1) Data requirements
One of the main challenges of applying Faster R-CNN to real-world scenarios is the data requirements. These models need large amounts of annotated data to train and fine-tune, which can be costly, time-consuming, and prone to errors. Moreover, the data needs to be representative of the target domain and scenario, which may not always be available or easy to obtain. To overcome this challenge, some possible solutions are to use data augmentation, transfer learning, synthetic data, or weakly supervised learning.
2) Computational complexity
Another challenge of applying Faster R-CNN to real-world scenarios is the computational complexity. These models have many layers and parameters, which require high-end hardware and resources to train and run. Moreover, these models can be slow to process images, especially when dealing with high-resolution or multiple objects. This can limit their applicability and scalability in scenarios that require real-time or low-latency performance. To overcome this challenge, some possible solutions are to use model compression, pruning, quantization, or hardware acceleration.
3) Generalization and robustness
A third challenge of applying Faster R-CNN to real-world scenarios is the generalization and robustness. These models can perform well on standard benchmarks and datasets, but they may not be able to handle variations and uncertainties in the real world. For example, these models may struggle with occlusions, distortions, illumination changes, background clutter, or adversarial attacks. These factors can affect the accuracy and reliability of the models, and potentially cause failures or harm. To overcome this challenge, some possible solutions are to use data diversity, regularization, adversarial training, or self-supervised learning.
4) Interpretability and explainability
A fourth challenge of applying Faster R-CNN to real-world scenarios is the interpretability and explainability. These models are often considered as black boxes, meaning that it is hard to understand how they make decisions and what features they use. This can pose problems for trust, accountability, and ethics, especially in scenarios that involve high-stakes or sensitive applications. For example, these models may produce false positives, false negatives, or biased results, which can have serious consequences or implications. To overcome this challenge, some possible solutions are to use visualization, attribution, or causal inference techniques.
5) Ethical and social issues
A fifth challenge of applying Faster R-CNN to real-world scenarios is ethical and social issues. These models can enable many beneficial and innovative applications, but they can also raise concerns and risks for privacy, security, human rights, and social justice. For example, these models may be used for surveillance, profiling, discrimination, or manipulation, which can violate the rights and interests of individuals or groups. To overcome this challenge, some possible solutions are to use privacy-preserving, secure, or fair methods, or to follow ethical guidelines and principles.
‘Object Detection’ deals with localizing a region of interest within an image and classifying this region like a typical image classifier. One image can include several regions of interest pointing to different objects. This makes object detection a more advanced problem of image classification.
YOLO (You Only Look Once) is a popular object detection model known for its speed and accuracy. It was first introduced by Joseph Redmon et al. in 2016 and has since undergone several iterations, the latest being YOLO v7. It is a single-shot detector that uses a fully convolutional neural network (CNN) to process an image.
YOLO proposes using an end-to-end neural network that makes predictions of bounding boxes and class probabilities all at once. It differs from the approach taken by previous object detection algorithms, which repurposed classifiers to perform detection. Following a fundamentally different approach to object detection, YOLO achieved state-of-the-art results, beating other real-time object detection algorithms by a large margin. The YOLO algorithm takes an image as input and then uses a simple deep convolutional neural network to detect objects in the image.
For this Capstone Project, we did try YOLO v3. It was introduced in 2018 as an improvement over YOLO v2, aiming to increase the accuracy and speed of the algorithm.
Improvements in YOLO v3:
Introduction YOLOv3 paper
import math
import os
import shutil
import sys
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import glob
import pydicom
import cv2
from sklearn.model_selection import train_test_split
from tqdm import tqdm
from darknet import *
random_stat = 123
np.random.seed(random_stat)
Clone and Build YOLOv3
!git clone https://github.com/pjreddie/darknet.git
Cloning into 'darknet'... remote: Enumerating objects: 5955, done. remote: Total 5955 (delta 0), reused 0 (delta 0), pack-reused 5955 Receiving objects: 100% (5955/5955), 6.37 MiB | 15.32 MiB/s, done. Resolving deltas: 100% (3931/3931), done.
!cd darknet && make -j 999 -s
!cp darknet/darknet darknet_gpu
Data Migration for YOLOv3
Make subdirectories
DATA_DIR = "/kaggle/input/pneumonia-dataset"
train_dcm_dir = os.path.join(DATA_DIR, "stage_2_train_images/stage_2_train_images")
test_dcm_dir = os.path.join(DATA_DIR, "stage_2_test_images/stage_2_test_images")
img_dir = os.path.join(os.getcwd(), "images") # .jpg
label_dir = os.path.join(os.getcwd(), "labels") # .txt
metadata_dir = os.path.join(os.getcwd(), "metadata") # .txt
# YOLOv3 config file directory
cfg_dir = os.path.join(os.getcwd(), "cfg")
# YOLOv3 training checkpoints will be saved here
backup_dir = os.path.join(os.getcwd(), "backup")
for directory in [img_dir, label_dir, metadata_dir, cfg_dir, backup_dir]:
if os.path.isdir(directory):
continue
os.mkdir(directory)
!ls -shtl
total 740K 4.0K drwxr-xr-x 2 root root 4.0K Sep 9 11:59 backup 4.0K drwxr-xr-x 2 root root 4.0K Sep 9 11:59 cfg 4.0K drwxr-xr-x 2 root root 4.0K Sep 9 11:59 metadata 4.0K drwxr-xr-x 2 root root 4.0K Sep 9 11:59 labels 4.0K drwxr-xr-x 2 root root 4.0K Sep 9 11:59 images 716K -rwxr-xr-x 1 root root 716K Sep 9 11:59 darknet_gpu 4.0K drwxr-xr-x 13 root root 4.0K Sep 9 11:55 darknet
Load stage_2_train_labels.csv
annots = pd.read_csv(os.path.join(DATA_DIR, "stage_2_train_labels.csv"))
annots.head()
| patientId | x | y | width | height | Target | |
|---|---|---|---|---|---|---|
| 0 | 0004cfab-14fd-4e49-80ba-63a80b6bddd6 | NaN | NaN | NaN | NaN | 0 |
| 1 | 00313ee0-9eaa-42f4-b0ab-c148ed3241cd | NaN | NaN | NaN | NaN | 0 |
| 2 | 00322d4d-1c29-4943-afc9-b6754be640eb | NaN | NaN | NaN | NaN | 0 |
| 3 | 003d8fa0-6bf1-40ed-b54c-ac657f8495c5 | NaN | NaN | NaN | NaN | 0 |
| 4 | 00436515-870c-4b36-a041-de91049b9ab4 | 264.0 | 152.0 | 213.0 | 379.0 | 1 |
Generate images and labels for training YOLOv3
<object-class> <x1> <y1> <w1> <h1>
<object-class> <x2> <y2> <w2> <h2>
object-class: Since RSNA task is binary classification basically,
x,y: Float values of bounding box center coordinate, divided by image width and height respectively.
w,h: Width and Height of boounding box, divided by image width and height respectively.
So it is different from the format of label data provided. Hence changing it below should change it.
def save_img_from_dcm_yolo(dcm_dir, img_dir, patient_id):
img_fp = os.path.join(img_dir, "{}.jpg".format(patient_id))
if os.path.exists(img_fp):
return
dcm_fp = os.path.join(dcm_dir, "{}.dcm".format(patient_id))
img_1ch = pydicom.read_file(dcm_fp).pixel_array
img_3ch = np.stack([img_1ch]*3, -1)
img_fp = os.path.join(img_dir, "{}.jpg".format(patient_id))
cv2.imwrite(img_fp, img_3ch)
def save_label_from_dcm_yolo(label_dir, patient_id, row=None):
# rsna defualt image size
img_size = 1024
label_fp = os.path.join(label_dir, "{}.txt".format(patient_id))
f = open(label_fp, "a")
if row is None:
f.close()
return
top_left_x = row[1]
top_left_y = row[2]
w = row[3]
h = row[4]
# 'r' means relative. 'c' means center.
rx = top_left_x/img_size
ry = top_left_y/img_size
rw = w/img_size
rh = h/img_size
rcx = rx+rw/2
rcy = ry+rh/2
line = "{} {} {} {} {}\n".format(0, rcx, rcy, rw, rh)
f.write(line)
f.close()
def save_yolov3_data_from_rsna(dcm_dir, img_dir, label_dir, annots):
for row in tqdm(annots.values):
patient_id = row[0]
img_fp = os.path.join(img_dir, "{}.jpg".format(patient_id))
if os.path.exists(img_fp):
save_label_from_dcm_yolo(label_dir, patient_id, row)
continue
target = row[5]
# In order to save space, limiting to files with bounding box
if target == 0:
continue
save_label_from_dcm_yolo(label_dir, patient_id, row)
save_img_from_dcm_yolo(dcm_dir, img_dir, patient_id)
save_yolov3_data_from_rsna(train_dcm_dir, img_dir, label_dir, annots)
100%|██████████| 30227/30227 [04:18<00:00, 117.03it/s]
!du -sh images labels
990M images 24M labels
Plot a sample train image and label
ex_patient_id = annots[annots.Target == 1].patientId.values[0]
ex_img_path = os.path.join(img_dir, "{}.jpg".format(ex_patient_id))
ex_label_path = os.path.join(label_dir, "{}.txt".format(ex_patient_id))
plt.imshow(cv2.imread(ex_img_path))
img_size = 1014
with open(ex_label_path, "r") as f:
for line in f:
print(line)
class_id, rcx, rcy, rw, rh = list(map(float, line.strip().split()))
x = (rcx-rw/2)*img_size
y = (rcy-rh/2)*img_size
w = rw*img_size
h = rh*img_size
plt.plot([x, x, x+w, x+w, x], [y, y+h, y+h, y, y])
0 0.36181640625 0.33349609375 0.2080078125 0.3701171875 0 0.673828125 0.36962890625 0.25 0.4423828125
Generate train/val file path list (.txt)
Giving the list of image paths to YOLO. two seperate list textfiles for training images and validation images.
def write_train_list_yolo(metadata_dir, img_dir, name, series):
list_fp = os.path.join(metadata_dir, name)
with open(list_fp, "w") as f:
for patient_id in series:
line = "{}\n".format(os.path.join(img_dir, "{}.jpg".format(patient_id)))
f.write(line)
# Lines without any bounding box is removed
patient_id_series = annots[annots.Target == 1].patientId.drop_duplicates()
tr_series, val_series = train_test_split(patient_id_series, test_size=0.1, random_state=random_stat)
print("The # of train set: {}, The # of validation set: {}".format(tr_series.shape[0], val_series.shape[0]))
# train image path list
write_train_list_yolo(metadata_dir, img_dir, "tr_list.txt", tr_series)
# validation image path list
write_train_list_yolo(metadata_dir, img_dir, "val_list.txt", val_series)
The # of train set: 5410, The # of validation set: 602
Create test image and labels for YOLOv3
def save_yolov3_test_data(test_dcm_dir, img_dir, metadata_dir, name, series):
list_fp = os.path.join(metadata_dir, name)
with open(list_fp, "w") as f:
for patient_id in series:
save_img_from_dcm_yolo(test_dcm_dir, img_dir, patient_id)
line = "{}\n".format(os.path.join(img_dir, "{}.jpg".format(patient_id)))
f.write(line)
test_dcm_fps = list(set(glob.glob(os.path.join(test_dcm_dir, '*.dcm'))))
test_dcm_fps = pd.Series(test_dcm_fps).apply(lambda dcm_fp: dcm_fp.strip().split("/")[-1].replace(".dcm",""))
save_yolov3_test_data(test_dcm_dir, img_dir, metadata_dir, "te_list.txt", test_dcm_fps)
Plot a sample test Image
ex_patient_id = test_dcm_fps[0]
print(ex_patient_id)
ex_img_path = os.path.join(img_dir, "{}.jpg".format(ex_patient_id))
plt.imshow(cv2.imread(ex_img_path))
1e3bf52d-b83e-4503-9b70-829b52d82269
<matplotlib.image.AxesImage at 0x794476917190>
ex_patient_id='76f71a93-8105-4c79-a010-0cfa86f0061a' #Picked the same image used in Milestone 1 (Patient having pneumonia with 4 bounding box)
ex_img_path = os.path.join(img_dir, "{}.jpg".format(ex_patient_id))
plt.imshow(cv2.imread(ex_img_path))
<matplotlib.image.AxesImage at 0x79447771d600>
Prepare Configuration Files for Using YOLOv3 pre-trained weights and config files are required for Yolo. cfg/rsna.data, cfg/rsna.names, darknet53.conv.74,cfg/rsna_yolov3.cfg_train cfg/rsna.data file point to RSNA data path
data_extention_file_path = os.path.join(cfg_dir, 'rsna.data')
with open(data_extention_file_path, 'w') as f:
contents = """classes= 1
train = {}
valid = {}
names = {}
backup = {}
""".format(os.path.join(metadata_dir, "tr_list.txt"),
os.path.join(metadata_dir, "val_list.txt"),
os.path.join(cfg_dir, 'rsna.names'),
backup_dir)
f.write(contents)
!cat cfg/rsna.data
classes= 1
train = /kaggle/working/metadata/tr_list.txt
valid = /kaggle/working/metadata/val_list.txt
names = /kaggle/working/cfg/rsna.names
backup = /kaggle/working/backup
# Label list of bounding box.
!echo "pneumonia" > cfg/rsna.names
For training, downloading pre-trained model weights(darknet53.conv.74) using wget command. Downloaded cfg file that was already edited for RSNA.
!wget -q https://pjreddie.com/media/files/darknet53.conv.74
!wget --no-check-certificate -q "https://docs.google.com/uc?export=download&id=18ptTK4Vbeokqpux8Onr0OmwUP9ipmcYO" -O cfg/rsna_yolov3.cfg_train
Training YOLOv3
Copy sample test image
ex_patient_id = annots[annots.Target == 1].patientId.values[2]
shutil.copy(ex_img_path, "test.jpg")
print(ex_patient_id)
00704310-78a8-4b38-8475-49f4573b2dbb
!wget --load-cookies /tmp/cookies.txt -q "https://docs.google.com/uc?export=download&confirm=$(wget --quiet --save-cookies /tmp/cookies.txt --keep-session-cookies --no-check-certificate 'https://docs.google.com/uc?export=download&id=1FDzMN-kGVYCvBeDKwemAazldSVkAEFyd' -O- | sed -rn 's/.*confirm=([0-9A-Za-z_]+).*/\1\n/p')&id=1FDzMN-kGVYCvBeDKwemAazldSVkAEFyd" -O backup/rsna_yolov3_15300.weights && rm -rf /tmp/cookies.txt
!ls -alsth backup
total 235M 4.0K drwxr-xr-x 2 root root 4.0K Sep 9 12:15 . 4.0K drwxr-xr-x 9 root root 4.0K Sep 9 12:14 .. 235M -rw-r--r-- 1 root root 235M Sep 23 2018 rsna_yolov3_15300.weights
configuration file for test (not for training)
!wget --no-check-certificate -q "https://docs.google.com/uc?export=download&id=10Yk6ZMAKGz5LeBbikciALy82aK3lX-57" -O cfg/rsna_yolov3.cfg_test
!cd darknet && ./darknet detector test ../cfg/rsna.data ../cfg/rsna_yolov3.cfg_test ../backup/rsna_yolov3_15300.weights ../test.jpg -thresh 0.005
layer filters size input output
0 conv 32 3 x 3 / 1 608 x 608 x 3 -> 608 x 608 x 32 0.639 BFLOPs
1 conv 64 3 x 3 / 2 608 x 608 x 32 -> 304 x 304 x 64 3.407 BFLOPs
2 conv 32 1 x 1 / 1 304 x 304 x 64 -> 304 x 304 x 32 0.379 BFLOPs
3 conv 64 3 x 3 / 1 304 x 304 x 32 -> 304 x 304 x 64 3.407 BFLOPs
4 res 1 304 x 304 x 64 -> 304 x 304 x 64
5 conv 128 3 x 3 / 2 304 x 304 x 64 -> 152 x 152 x 128 3.407 BFLOPs
6 conv 64 1 x 1 / 1 152 x 152 x 128 -> 152 x 152 x 64 0.379 BFLOPs
7 conv 128 3 x 3 / 1 152 x 152 x 64 -> 152 x 152 x 128 3.407 BFLOPs
8 res 5 152 x 152 x 128 -> 152 x 152 x 128
9 conv 64 1 x 1 / 1 152 x 152 x 128 -> 152 x 152 x 64 0.379 BFLOPs
10 conv 128 3 x 3 / 1 152 x 152 x 64 -> 152 x 152 x 128 3.407 BFLOPs
11 res 8 152 x 152 x 128 -> 152 x 152 x 128
12 conv 256 3 x 3 / 2 152 x 152 x 128 -> 76 x 76 x 256 3.407 BFLOPs
13 conv 128 1 x 1 / 1 76 x 76 x 256 -> 76 x 76 x 128 0.379 BFLOPs
14 conv 256 3 x 3 / 1 76 x 76 x 128 -> 76 x 76 x 256 3.407 BFLOPs
15 res 12 76 x 76 x 256 -> 76 x 76 x 256
16 conv 128 1 x 1 / 1 76 x 76 x 256 -> 76 x 76 x 128 0.379 BFLOPs
17 conv 256 3 x 3 / 1 76 x 76 x 128 -> 76 x 76 x 256 3.407 BFLOPs
18 res 15 76 x 76 x 256 -> 76 x 76 x 256
19 conv 128 1 x 1 / 1 76 x 76 x 256 -> 76 x 76 x 128 0.379 BFLOPs
20 conv 256 3 x 3 / 1 76 x 76 x 128 -> 76 x 76 x 256 3.407 BFLOPs
21 res 18 76 x 76 x 256 -> 76 x 76 x 256
22 conv 128 1 x 1 / 1 76 x 76 x 256 -> 76 x 76 x 128 0.379 BFLOPs
23 conv 256 3 x 3 / 1 76 x 76 x 128 -> 76 x 76 x 256 3.407 BFLOPs
24 res 21 76 x 76 x 256 -> 76 x 76 x 256
25 conv 128 1 x 1 / 1 76 x 76 x 256 -> 76 x 76 x 128 0.379 BFLOPs
26 conv 256 3 x 3 / 1 76 x 76 x 128 -> 76 x 76 x 256 3.407 BFLOPs
27 res 24 76 x 76 x 256 -> 76 x 76 x 256
28 conv 128 1 x 1 / 1 76 x 76 x 256 -> 76 x 76 x 128 0.379 BFLOPs
29 conv 256 3 x 3 / 1 76 x 76 x 128 -> 76 x 76 x 256 3.407 BFLOPs
30 res 27 76 x 76 x 256 -> 76 x 76 x 256
31 conv 128 1 x 1 / 1 76 x 76 x 256 -> 76 x 76 x 128 0.379 BFLOPs
32 conv 256 3 x 3 / 1 76 x 76 x 128 -> 76 x 76 x 256 3.407 BFLOPs
33 res 30 76 x 76 x 256 -> 76 x 76 x 256
34 conv 128 1 x 1 / 1 76 x 76 x 256 -> 76 x 76 x 128 0.379 BFLOPs
35 conv 256 3 x 3 / 1 76 x 76 x 128 -> 76 x 76 x 256 3.407 BFLOPs
36 res 33 76 x 76 x 256 -> 76 x 76 x 256
37 conv 512 3 x 3 / 2 76 x 76 x 256 -> 38 x 38 x 512 3.407 BFLOPs
38 conv 256 1 x 1 / 1 38 x 38 x 512 -> 38 x 38 x 256 0.379 BFLOPs
39 conv 512 3 x 3 / 1 38 x 38 x 256 -> 38 x 38 x 512 3.407 BFLOPs
40 res 37 38 x 38 x 512 -> 38 x 38 x 512
41 conv 256 1 x 1 / 1 38 x 38 x 512 -> 38 x 38 x 256 0.379 BFLOPs
42 conv 512 3 x 3 / 1 38 x 38 x 256 -> 38 x 38 x 512 3.407 BFLOPs
43 res 40 38 x 38 x 512 -> 38 x 38 x 512
44 conv 256 1 x 1 / 1 38 x 38 x 512 -> 38 x 38 x 256 0.379 BFLOPs
45 conv 512 3 x 3 / 1 38 x 38 x 256 -> 38 x 38 x 512 3.407 BFLOPs
46 res 43 38 x 38 x 512 -> 38 x 38 x 512
47 conv 256 1 x 1 / 1 38 x 38 x 512 -> 38 x 38 x 256 0.379 BFLOPs
48 conv 512 3 x 3 / 1 38 x 38 x 256 -> 38 x 38 x 512 3.407 BFLOPs
49 res 46 38 x 38 x 512 -> 38 x 38 x 512
50 conv 256 1 x 1 / 1 38 x 38 x 512 -> 38 x 38 x 256 0.379 BFLOPs
51 conv 512 3 x 3 / 1 38 x 38 x 256 -> 38 x 38 x 512 3.407 BFLOPs
52 res 49 38 x 38 x 512 -> 38 x 38 x 512
53 conv 256 1 x 1 / 1 38 x 38 x 512 -> 38 x 38 x 256 0.379 BFLOPs
54 conv 512 3 x 3 / 1 38 x 38 x 256 -> 38 x 38 x 512 3.407 BFLOPs
55 res 52 38 x 38 x 512 -> 38 x 38 x 512
56 conv 256 1 x 1 / 1 38 x 38 x 512 -> 38 x 38 x 256 0.379 BFLOPs
57 conv 512 3 x 3 / 1 38 x 38 x 256 -> 38 x 38 x 512 3.407 BFLOPs
58 res 55 38 x 38 x 512 -> 38 x 38 x 512
59 conv 256 1 x 1 / 1 38 x 38 x 512 -> 38 x 38 x 256 0.379 BFLOPs
60 conv 512 3 x 3 / 1 38 x 38 x 256 -> 38 x 38 x 512 3.407 BFLOPs
61 res 58 38 x 38 x 512 -> 38 x 38 x 512
62 conv 1024 3 x 3 / 2 38 x 38 x 512 -> 19 x 19 x1024 3.407 BFLOPs
63 conv 512 1 x 1 / 1 19 x 19 x1024 -> 19 x 19 x 512 0.379 BFLOPs
64 conv 1024 3 x 3 / 1 19 x 19 x 512 -> 19 x 19 x1024 3.407 BFLOPs
65 res 62 19 x 19 x1024 -> 19 x 19 x1024
66 conv 512 1 x 1 / 1 19 x 19 x1024 -> 19 x 19 x 512 0.379 BFLOPs
67 conv 1024 3 x 3 / 1 19 x 19 x 512 -> 19 x 19 x1024 3.407 BFLOPs
68 res 65 19 x 19 x1024 -> 19 x 19 x1024
69 conv 512 1 x 1 / 1 19 x 19 x1024 -> 19 x 19 x 512 0.379 BFLOPs
70 conv 1024 3 x 3 / 1 19 x 19 x 512 -> 19 x 19 x1024 3.407 BFLOPs
71 res 68 19 x 19 x1024 -> 19 x 19 x1024
72 conv 512 1 x 1 / 1 19 x 19 x1024 -> 19 x 19 x 512 0.379 BFLOPs
73 conv 1024 3 x 3 / 1 19 x 19 x 512 -> 19 x 19 x1024 3.407 BFLOPs
74 res 71 19 x 19 x1024 -> 19 x 19 x1024
75 conv 512 1 x 1 / 1 19 x 19 x1024 -> 19 x 19 x 512 0.379 BFLOPs
76 conv 1024 3 x 3 / 1 19 x 19 x 512 -> 19 x 19 x1024 3.407 BFLOPs
77 conv 512 1 x 1 / 1 19 x 19 x1024 -> 19 x 19 x 512 0.379 BFLOPs
78 conv 1024 3 x 3 / 1 19 x 19 x 512 -> 19 x 19 x1024 3.407 BFLOPs
79 conv 512 1 x 1 / 1 19 x 19 x1024 -> 19 x 19 x 512 0.379 BFLOPs
80 conv 1024 3 x 3 / 1 19 x 19 x 512 -> 19 x 19 x1024 3.407 BFLOPs
81 conv 18 1 x 1 / 1 19 x 19 x1024 -> 19 x 19 x 18 0.013 BFLOPs
82 yolo
83 route 79
84 conv 256 1 x 1 / 1 19 x 19 x 512 -> 19 x 19 x 256 0.095 BFLOPs
85 upsample 2x 19 x 19 x 256 -> 38 x 38 x 256
86 route 85 61
87 conv 256 1 x 1 / 1 38 x 38 x 768 -> 38 x 38 x 256 0.568 BFLOPs
88 conv 512 3 x 3 / 1 38 x 38 x 256 -> 38 x 38 x 512 3.407 BFLOPs
89 conv 256 1 x 1 / 1 38 x 38 x 512 -> 38 x 38 x 256 0.379 BFLOPs
90 conv 512 3 x 3 / 1 38 x 38 x 256 -> 38 x 38 x 512 3.407 BFLOPs
91 conv 256 1 x 1 / 1 38 x 38 x 512 -> 38 x 38 x 256 0.379 BFLOPs
92 conv 512 3 x 3 / 1 38 x 38 x 256 -> 38 x 38 x 512 3.407 BFLOPs
93 conv 18 1 x 1 / 1 38 x 38 x 512 -> 38 x 38 x 18 0.027 BFLOPs
94 yolo
95 route 91
96 conv 128 1 x 1 / 1 38 x 38 x 256 -> 38 x 38 x 128 0.095 BFLOPs
97 upsample 2x 38 x 38 x 128 -> 76 x 76 x 128
98 route 97 36
99 conv 128 1 x 1 / 1 76 x 76 x 384 -> 76 x 76 x 128 0.568 BFLOPs
100 conv 256 3 x 3 / 1 76 x 76 x 128 -> 76 x 76 x 256 3.407 BFLOPs
101 conv 128 1 x 1 / 1 76 x 76 x 256 -> 76 x 76 x 128 0.379 BFLOPs
102 conv 256 3 x 3 / 1 76 x 76 x 128 -> 76 x 76 x 256 3.407 BFLOPs
103 conv 128 1 x 1 / 1 76 x 76 x 256 -> 76 x 76 x 128 0.379 BFLOPs
104 conv 256 3 x 3 / 1 76 x 76 x 128 -> 76 x 76 x 256 3.407 BFLOPs
105 conv 18 1 x 1 / 1 76 x 76 x 256 -> 76 x 76 x 18 0.053 BFLOPs
106 yolo
Loading weights from ../backup/rsna_yolov3_15300.weights...Done!
../test.jpg: Predicted in 35.566967 seconds.
pneumonia: 65%
pneumonia: 29%
pneumonia: 16%
pneumonia: 5%
pneumonia: 3%
plt.imshow(cv2.imread("./darknet/predictions.jpg"))
<matplotlib.image.AxesImage at 0x794477503160>
Actual Bounding Box Information for the Patient
sample_id = '76f71a93-8105-4c79-a010-0cfa86f0061a'
display_one_image(sample_id, four_bbox_df[four_bbox_df['patientId'] == sample_id])
Observation
Due to its anchor box design and large stride, YOLOv3 struggles to detect smaller objects. There is High Memory Requirements: YOLOv3 requires a significant amount of memory to run, which can be a challenge for devices with limited resources. The model was able to predict test images but was failing when the complete test folder was given as input for prediction due to memory issues. Hence, more powerful and better computational environment needs to be used for generating the prediction.
YOLOv3 Advantages
Fast and Efficient: YOLOv3 is designed to be fast and efficient, making it ideal for real-time applications such as self-driving cars and surveillance systems.
High Accuracy: YOLOv3 can achieve high accuracy in object detection while still being fast, thanks to its feature pyramid network and prediction module.
One-Stage Detection: Unlike traditional object detection models that use multiple stages, YOLOv3 uses a single neural network for detection, making it simpler and easier to implement.
Generalization: YOLOv3 can detect objects in a wide range of settings and scenarios, making it a versatile model.
An example of YOLOv3's advantages can be seen in self-driving cars, where real-time object detection is critical for the car's safety. YOLOv3's speed and accuracy can help the car detect objects such as pedestrians, other vehicles, and traffic signals quickly and react accordingly.
YOLOv3 Disadvantages
Smaller Objects Detection: YOLOv3 can struggle to detect smaller objects due to its anchor box design and large stride.
High Memory Requirements: YOLOv3 requires a significant amount of memory to run, which can be a challenge for devices with limited resources.
Training Time: Training YOLOv3 can be time-consuming, requiring large amounts of data and computational resources.
detection_threshold = 0.8
results = []
model.eval()
with torch.no_grad():
for i, image in tqdm(enumerate(test_images), total=len(test_images)):
# plot image
orig_image = pydicom.read_file(os.path.join(images_test_path + '%s' % image))
image = orig_image.pixel_array
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB).astype(np.float32)
image /= 255.0
image = np.transpose(image, (2, 0, 1)).astype(np.float32)
image = torch.tensor(image, dtype=torch.float).cuda()
image = torch.unsqueeze(image, 0)
model.eval()
cpu_device = torch.device("cpu")
outputs = model(image)
outputs = [{k: v.to(cpu_device) for k, v in t.items()} for t in outputs]
if len(outputs[0]['boxes']) != 0:
for counter in range(len(outputs[0]['boxes'])):
boxes = outputs[0]['boxes'].data.cpu().numpy()
scores = outputs[0]['scores'].data.cpu().numpy()
boxes = boxes[scores >= detection_threshold].astype(np.int32)
draw_boxes = boxes.copy()
boxes[:, 2] = boxes[:, 2] - boxes[:, 0]
boxes[:, 3] = boxes[:, 3] - boxes[:, 1]
draw_boxes = boxes.copy()
result = {
'patientId': test_images[i].split('.')[0],
'PredictionString': format_prediction_string(boxes, scores)
}
results.append(result)
else:
result = {
'patientId': test_images[i].split('.')[0],
'PredictionString': ''
}
results.append(result)
sub_df = pd.DataFrame(results, columns=['patientId', 'PredictionString'])
print(sub_df.head())
sub_df.to_csv('submission_frcnn.csv', index=False)
100%|██████████| 3000/3000 [06:00<00:00, 8.33it/s]
patientId \
0 12abc170-f1fe-45d3-b574-2f4d030e40cd
1 2abcf934-facd-40fc-a75e-0062441fd206
2 2da69f80-c59d-4e4a-b7e5-1d631ef4186b
3 13e4e6e6-faa2-4bbc-8e1e-610623de994e
4 2afe02a3-06da-42fa-b68f-3e9c921e5fb9
PredictionString
0
1 0.9593 561 275 173 436 0.9328 197 298 181 341
2 0.8360 235 456 146 139
3
4
Prediction of bounding boxes with Confidence Score for the test images. Out of total of 3000 images, 1098 images have been detected as Pneumonia cases with one or more bounding boxes.
sub_df[sub_df['PredictionString']!='']
| patientId | PredictionString | |
|---|---|---|
| 1 | 2abcf934-facd-40fc-a75e-0062441fd206 | 0.9593 561 275 173 436 0.9328 197 298 181 341 |
| 2 | 2da69f80-c59d-4e4a-b7e5-1d631ef4186b | 0.8360 235 456 146 139 |
| 6 | 2a7df7aa-1314-40da-afc5-7af58ad1bee9 | 0.9230 142 344 211 421 |
| 8 | 0de33fbf-998c-4c91-9561-df7343873bc2 | 0.9313 646 533 184 193 |
| 9 | 1eeecd10-16a2-476f-8d81-867d5480bf01 | 0.9270 256 481 176 151 0.8682 637 438 173 228 |
| ... | ... | ... |
| 2985 | 140ebc5d-5a15-4948-b698-0a4b32d12a93 | 0.8276 144 359 228 491 |
| 2989 | 26586d01-b992-41c4-a7a4-c9f1f8d102ad | 0.9242 192 396 212 336 0.8151 625 434 189 383 |
| 2990 | 23ebfb85-2312-4a8b-8879-3cf48a1e8920 | 0.9041 646 367 200 382 |
| 2991 | 2dbac7d7-9100-4861-8e15-fa2adf82c6e3 | 0.8707 758 264 217 432 0.8068 285 252 240 408 |
| 2997 | 20da1944-1714-4170-a08a-8b82c0788ad5 | 0.8825 200 502 197 113 |
1098 rows × 2 columns
For Demonstration purposes, displaying sample images with actual and predicted bounding box.
#1352a7f3-1f0d-4f1f-af05-daa5d7f8624a
dataset = valid_df
f, axarr = plt.subplots(6, 2, figsize=(16,36))
axarr = axarr.ravel()
axidx = 0
image_id = valid_df.sample(6)['patientId'].reset_index(drop=True)
for i in range(6):
show_image_with_bboxes(image_id[i],axarr,axidx)
axidx+=1
show_pred_image_with_bboxes(image_id[i],axarr,axidx)
axidx+=1
Yolov3 was able to predict the test images with good performace. But Faster-RCNN predicted 1098 test images out of 3000 samples with high confidence score. Hence, pickle Faster RCNN model for further tuning in next phase of project.
torch.save(model.state_dict(), 'fasterrcnn_resnet50_fpn_pneumonia_detection.pth')
We tried various models to achieve our goal of building a model with minimal computational resources so that faster and accurate results can be brought out in the healthcare industry, especially the imaging side as it is very computationally heavy. Using the existing data, it was possible to train several models with different configurations and parameters whose accuracies vary between ∼74% and ∼97%; we can conclude that the model's capabilities can be expanded if sufficient training data and advanced computational capability to run further iterations is available as the loss was still decreasing.
In this work, we have presented our approach for identifying pneumonia and understanding how the lung image size plays an important role for the model performance. We found that the distinction is quite subtle for images among presence or absence of pneumonia, large image can be more beneficial for deeper information. However, the computation cost also burden exponentially when dealing with large image.
Our proposed architecture with regional context RCNN with selective search supplied extra context for generating accurate results. Also, using thresholds in background while training tuned our network to perform well in this task. With the usage of image augmentation, dropout and L2 regularization prevented the overfitting, but are obtained something weaker results on the training set with respect to the test. Our model can be improved by adding new layers, but this would introduce even more hyperparameters that should be adjusted. We intend to extend our model architecture in other areas of medical imaging with the usage of deep learning and computer vision techniques.
RCNN with selective search has very limited application for Dicom image analysis due to its architecture. The performance of other models has been better as compared to RCNN. Yolov3 was able to predict the test images with good performance. But Faster-RCNN predicted 1098 test images out of 3000 samples with high confidence score. Hence, both YOLO and Faster RCNN can be taken up for further tuning in next phase of project.
Improvements Area:
While the results are promising, there are several avenues for future research: • Clinical Validation: Our model needs to be tested in a real-world clinical setting to assess its efficacy and reliability further. • Model Explainability: Future work can also focus on making the model more interpretable for clinicians, possibly through the use of attention mechanisms or other explainability techniques. • Multi-Modal Approaches: Incorporating additional data types, like patient history or other diagnostic tests, could potentially improve the model's predictive power. • Low-Resource Settings: Optimizing the model for deployment in low-resource settings could have a significant impact, making high-quality diagnosis accessible to underserved populations.
In future, it would be interesting to see or use medical dataset repository as it would be instrumental in advancing computer vision and deep learning research for medical field. As more and more advanced architectures are emerging, we can look at more accurate classification and localization models to diagnose pneumonia. We could also look at a historical progressive monitoring of the patient and affected region, assisting the pulmonologist in a visual analysis of the patient’s on-going condition.